Merge sc-qpr1 to aosp-master - DO NOT MERGE
Merged-In: I610c38c3dfa143a57a744ddf8de5be930b00abff
Merged-In: I71258c6be83f1dd264c8be7445c08bb726b432ed
Change-Id: I2ec41562b311894742615d7a3e4237085162db46
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..a7614d2
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,13 @@
+BasedOnStyle: Google
+Standard: Cpp11
+AccessModifierOffset: -2
+AllowShortFunctionsOnASingleLine: Inline
+ColumnLimit: 100
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+IncludeBlocks: Preserve
+IndentWidth: 4
+ContinuationIndentWidth: 8
+PointerAlignment: Left
+TabWidth: 4
+UseTab: Never
diff --git a/Android.bp b/Android.bp
index 60f0ff1..ee609e1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -57,7 +57,7 @@
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth.updatable",
+ "com.android.bluetooth",
"com.android.media",
"com.android.media.swcodec",
],
@@ -86,7 +86,7 @@
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth.updatable",
+ "com.android.bluetooth",
"com.android.media",
"com.android.media.swcodec",
],
diff --git a/apex/OWNERS b/apex/OWNERS
index 5587f5f..54802d4 100644
--- a/apex/OWNERS
+++ b/apex/OWNERS
@@ -1,6 +1,7 @@
-chz@google.com
-dwkang@google.com
+essick@google.com
jiyong@google.com
lajos@google.com
-marcone@google.com
-wjia@google.com
+nchalko@google.com
+
+include platform/packages/modules/common:/MODULES_OWNERS
+
diff --git a/apex/mediaswcodec.32rc b/apex/mediaswcodec.32rc
new file mode 100644
index 0000000..79aef36
--- /dev/null
+++ b/apex/mediaswcodec.32rc
@@ -0,0 +1,6 @@
+service media.swcodec /apex/com.android.media.swcodec/bin/mediaswcodec
+ class main
+ user mediacodec
+ group camera drmrpc mediadrm
+ ioprio rt 4
+ task_profiles ProcessCapacityHigh
diff --git a/apex/mediatranscoding.32rc b/apex/mediatranscoding.32rc
new file mode 100644
index 0000000..5169462
--- /dev/null
+++ b/apex/mediatranscoding.32rc
@@ -0,0 +1,12 @@
+# media.transcoding service is defined on com.android.media apex which goes back
+# to API29, but we only want it started on API31+ devices. So we declare it as
+# "disabled" and start it explicitly on boot.
+service media.transcoding /apex/com.android.media/bin/mediatranscoding
+ class main
+ user media
+ group media
+ ioprio rt 4
+ # Restrict to little cores only with system-background cpuset.
+ task_profiles ServiceCapacityLow
+ interface aidl media.transcoding
+ disabled
diff --git a/camera/Android.bp b/camera/Android.bp
index 6878c20..4ed3269 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -43,6 +43,10 @@
],
}
+cc_library_headers {
+ name: "camera_headers",
+ export_include_dirs: ["include"],
+}
cc_library_shared {
name: "libcamera_client",
diff --git a/camera/OWNERS b/camera/OWNERS
index d6b95da..385c163 100644
--- a/camera/OWNERS
+++ b/camera/OWNERS
@@ -1,8 +1,7 @@
-epeev@google.com
+# Bug component: 41727
etalvala@google.com
+arakesh@google.com
+epeev@google.com
jchowdhary@google.com
shuzhenwang@google.com
-yinchiayeh@google.com
-# backup owner
-cychen@google.com
-zhijunhe@google.com
+ruchamk@google.com
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index ccbfaa9..da887a2 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -139,6 +139,8 @@
return !(*this == other);
}
bool operator < (const Callback& other) const {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wordered-compare-function-pointers"
if (*this == other) return false;
if (mContext != other.mContext) return mContext < other.mContext;
if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) {
@@ -152,6 +154,7 @@
}
if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
return mUnavailable < other.mUnavailable;
+#pragma GCC diagnostic pop
}
bool operator > (const Callback& other) const {
return (*this != other && !(*this < other));
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index dab2fef..05124c0 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -182,7 +182,7 @@
int64_t format = entry.data.i64[i + STREAM_FORMAT_OFFSET];
int64_t width = entry.data.i64[i + STREAM_WIDTH_OFFSET];
int64_t height = entry.data.i64[i + STREAM_HEIGHT_OFFSET];
- int64_t duration = entry.data.i32[i + STREAM_DURATION_OFFSET];
+ int64_t duration = entry.data.i64[i + STREAM_DURATION_OFFSET];
// Leave the unfiltered format in so apps depending on previous wrong
// filter behavior continue to work
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index 8359bb1..4663529 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -136,6 +136,8 @@
return !(*this == other);
}
bool operator < (const Callback& other) const {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wordered-compare-function-pointers"
if (*this == other) return false;
if (mContext != other.mContext) return mContext < other.mContext;
if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
@@ -146,6 +148,7 @@
if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable)
return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable;
return mUnavailable < other.mUnavailable;
+#pragma GCC diagnostic pop
}
bool operator > (const Callback& other) const {
return (*this != other && !(*this < other));
diff --git a/cmds/OWNERS b/cmds/OWNERS
index 0d32aac..a48c37a 100644
--- a/cmds/OWNERS
+++ b/cmds/OWNERS
@@ -1,3 +1,3 @@
elaurent@google.com
+essick@google.com
lajos@google.com
-marcone@google.com
diff --git a/cmds/stagefright/Android.bp b/cmds/stagefright/Android.bp
new file mode 100644
index 0000000..c4783d3
--- /dev/null
+++ b/cmds/stagefright/Android.bp
@@ -0,0 +1,278 @@
+package {
+ default_applicable_licenses: ["frameworks_av_cmds_stagefright_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+ name: "frameworks_av_cmds_stagefright_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
+cc_binary {
+ name: "stagefright",
+
+ srcs: [
+ "AudioPlayer.cpp",
+ "stagefright.cpp",
+ "jpeg.cpp",
+ "SineSource.cpp",
+ ],
+
+ header_libs: [
+ "libmediametrics_headers",
+ "libstagefright_headers",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "libmedia",
+ "libmedia_codeclist",
+ "libutils",
+ "libbinder",
+ "libstagefright_foundation",
+ "libjpeg",
+ "libui",
+ "libgui",
+ "libcutils",
+ "liblog",
+ "libhidlbase",
+ "libdatasource",
+ "libaudioclient",
+ "android.hardware.media.omx@1.0",
+ "framework-permission-aidl-cpp",
+ ],
+
+ static_libs: ["framework-permission-aidl-cpp"],
+
+ cflags: [
+ "-Wno-multichar",
+ ],
+
+ system_ext_specific: true,
+}
+
+cc_binary {
+ name: "record",
+
+ srcs: [
+ "AudioPlayer.cpp",
+ "SineSource.cpp",
+ "record.cpp",
+ ],
+
+ header_libs: [
+ "libmediametrics_headers",
+ "libstagefright_headers",
+ "camera_headers",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "libmedia",
+ "liblog",
+ "libutils",
+ "libbinder",
+ "libstagefright_foundation",
+ "libdatasource",
+ "libaudioclient",
+ "framework-permission-aidl-cpp",
+ ],
+
+ cflags: [
+ "-Wno-multichar",
+ ],
+}
+
+cc_binary {
+ name: "recordvideo",
+
+ srcs: [
+ "AudioPlayer.cpp",
+ "recordvideo.cpp",
+ ],
+
+ header_libs: [
+ "libmediametrics_headers",
+ "libstagefright_headers",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "libmedia",
+ "liblog",
+ "libutils",
+ "libbinder",
+ "libstagefright_foundation",
+ "libaudioclient",
+ "framework-permission-aidl-cpp",
+ ],
+
+ cflags: [
+ "-Wno-multichar",
+ ],
+}
+
+cc_binary {
+ name: "audioloop",
+
+ srcs: [
+ "AudioPlayer.cpp",
+ "SineSource.cpp",
+ "audioloop.cpp",
+ ],
+
+ header_libs: [
+ "libmediametrics_headers",
+ "libstagefright_headers",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "libmedia",
+ "liblog",
+ "libutils",
+ "libbinder",
+ "libstagefright_foundation",
+ "libaudioclient",
+ "framework-permission-aidl-cpp",
+ ],
+
+ cflags: [
+ "-Wno-multichar",
+ ],
+}
+
+cc_binary {
+ name: "stream",
+
+ srcs: ["stream.cpp"],
+
+ header_libs: [
+ "libmediametrics_headers",
+ "libstagefright_headers",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "liblog",
+ "libutils",
+ "libbinder",
+ "libui",
+ "libgui",
+ "libstagefright_foundation",
+ "libmedia",
+ "libcutils",
+ "libdatasource",
+ ],
+
+ cflags: [
+ "-Wno-multichar",
+ ],
+}
+
+cc_binary {
+ name: "codec",
+
+ srcs: [
+ "codec.cpp",
+ "SimplePlayer.cpp",
+ ],
+
+ header_libs: [
+ "libmediadrm_headers",
+ "libmediametrics_headers",
+ "libstagefright_headers",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "liblog",
+ "libutils",
+ "libbinder",
+ "libstagefright_foundation",
+ "libmedia",
+ "libmedia_omx",
+ "libaudioclient",
+ "libui",
+ "libgui",
+ "libcutils",
+ ],
+
+ cflags: [
+ "-Wno-multichar",
+ ],
+}
+
+cc_binary {
+ name: "mediafilter",
+
+ srcs: [
+ "filters/argbtorgba.rscript",
+ "filters/nightvision.rscript",
+ "filters/saturation.rscript",
+ "mediafilter.cpp",
+ ],
+
+ header_libs: [
+ "libmediadrm_headers",
+ "libmediametrics_headers",
+ "libstagefright_headers",
+ "rs-headers",
+ ],
+
+ include_dirs: ["frameworks/av/media/libstagefright"],
+
+ shared_libs: [
+ "libstagefright",
+ "liblog",
+ "libutils",
+ "libbinder",
+ "libstagefright_foundation",
+ "libmedia_omx",
+ "libui",
+ "libgui",
+ "libRScpp",
+ ],
+
+ static_libs: ["libstagefright_mediafilter"],
+
+ cflags: [
+ "-Wno-multichar",
+ ],
+
+ sanitize: {
+ cfi: true,
+ },
+}
+
+cc_binary {
+ name: "muxer",
+
+ srcs: ["muxer.cpp"],
+
+ header_libs: [
+ "libmediametrics_headers",
+ "libstagefright_headers",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "liblog",
+ "libutils",
+ "libbinder",
+ "libstagefright_foundation",
+ "libcutils",
+ "libc",
+ ],
+
+ cflags: [
+ "-Wno-multichar",
+ ],
+}
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
deleted file mode 100644
index 803c4a4..0000000
--- a/cmds/stagefright/Android.mk
+++ /dev/null
@@ -1,276 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- AudioPlayer.cpp \
- stagefright.cpp \
- jpeg.cpp \
- SineSource.cpp
-
-LOCAL_HEADER_LIBRARIES := \
- libmediametrics_headers \
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libmedia_codeclist libutils libbinder \
- libstagefright_foundation libjpeg libui libgui libcutils liblog \
- libhidlbase libdatasource libaudioclient \
- android.hardware.media.omx@1.0 \
- framework-permission-aidl-cpp
-
-LOCAL_STATIC_LIBRARIES := framework-permission-aidl-cpp
-
-LOCAL_C_INCLUDES:= \
- frameworks/av/media/libstagefright \
- frameworks/av/media/libstagefright/include \
- frameworks/native/include/media/openmax \
-
-LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SYSTEM_EXT_MODULE:= true
-LOCAL_MODULE:= stagefright
-LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS:= notice
-LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/NOTICE
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- AudioPlayer.cpp \
- SineSource.cpp \
- record.cpp
-
-LOCAL_HEADER_LIBRARIES := \
- libmediametrics_headers \
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia liblog libutils libbinder \
- libstagefright_foundation libdatasource libaudioclient \
- framework-permission-aidl-cpp
-
-LOCAL_C_INCLUDES:= \
- frameworks/av/camera/include \
- frameworks/av/media/libstagefright \
- frameworks/native/include/media/openmax \
- frameworks/native/include/media/hardware
-
-LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= record
-LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS:= notice
-LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/NOTICE
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- AudioPlayer.cpp \
- recordvideo.cpp
-
-LOCAL_HEADER_LIBRARIES := \
- libmediametrics_headers \
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia liblog libutils libbinder \
- libstagefright_foundation libaudioclient
-
-LOCAL_C_INCLUDES:= \
- frameworks/av/media/libstagefright \
- frameworks/native/include/media/openmax \
- frameworks/native/include/media/hardware \
- framework-permission-aidl-cpp
-
-LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= recordvideo
-LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS:= notice
-LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/NOTICE
-
-include $(BUILD_EXECUTABLE)
-
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- AudioPlayer.cpp \
- SineSource.cpp \
- audioloop.cpp
-
-LOCAL_HEADER_LIBRARIES := \
- libmediametrics_headers \
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia liblog libutils libbinder \
- libstagefright_foundation libaudioclient \
- framework-permission-aidl-cpp
-
-LOCAL_C_INCLUDES:= \
- frameworks/av/media/libstagefright \
- frameworks/native/include/media/openmax
-
-LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= audioloop
-LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS:= notice
-LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/NOTICE
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- stream.cpp \
-
-LOCAL_HEADER_LIBRARIES := \
- libmediametrics_headers \
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright liblog libutils libbinder libui libgui \
- libstagefright_foundation libmedia libcutils libdatasource
-
-LOCAL_C_INCLUDES:= \
- frameworks/av/media/libstagefright \
- frameworks/native/include/media/openmax
-
-LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= stream
-LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS:= notice
-LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/NOTICE
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- codec.cpp \
- SimplePlayer.cpp \
-
-LOCAL_HEADER_LIBRARIES := \
- libmediadrm_headers \
- libmediametrics_headers \
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libmedia_omx libaudioclient libui libgui libcutils
-
-LOCAL_C_INCLUDES:= \
- frameworks/av/media/libstagefright \
- frameworks/native/include/media/openmax
-
-LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= codec
-LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS:= notice
-LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/NOTICE
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- filters/argbtorgba.rscript \
- filters/nightvision.rscript \
- filters/saturation.rscript \
- mediafilter.cpp \
-
-LOCAL_HEADER_LIBRARIES := \
- libmediadrm_headers \
- libmediametrics_headers \
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright \
- liblog \
- libutils \
- libbinder \
- libstagefright_foundation \
- libmedia_omx \
- libui \
- libgui \
- libRScpp \
-
-LOCAL_C_INCLUDES:= \
- frameworks/av/media/libstagefright \
- frameworks/native/include/media/openmax \
- frameworks/rs/cpp \
- frameworks/rs \
-
-intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,)
-LOCAL_C_INCLUDES += $(intermediates)
-
-LOCAL_STATIC_LIBRARIES:= \
- libstagefright_mediafilter
-
-LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= mediafilter
-LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS:= notice
-LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/NOTICE
-
-LOCAL_SANITIZE := cfi
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- muxer.cpp \
-
-LOCAL_HEADER_LIBRARIES := \
- libmediametrics_headers \
-
-LOCAL_SHARED_LIBRARIES := \
- libstagefright liblog libutils libbinder libstagefright_foundation \
- libcutils libc
-
-LOCAL_C_INCLUDES:= \
- frameworks/av/media/libstagefright \
- frameworks/native/include/media/openmax
-
-LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= muxer
-LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS:= notice
-LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/NOTICE
-
-include $(BUILD_EXECUTABLE)
diff --git a/drm/drmserver/drmserver.rc b/drm/drmserver/drmserver.rc
index eb176c1..0319ff9 100644
--- a/drm/drmserver/drmserver.rc
+++ b/drm/drmserver/drmserver.rc
@@ -3,7 +3,7 @@
class main
user drm
group drm system inet drmrpc readproc
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
on property:drm.service.enabled=true
start drm
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 0ffe626..71df58c 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -66,7 +66,7 @@
],
static_libs: [
- "resourcemanager_aidl_interface-ndk_platform",
+ "resourcemanager_aidl_interface-ndk",
],
export_shared_lib_headers: [
diff --git a/drm/libmediadrm/fuzzer/Android.bp b/drm/libmediadrm/fuzzer/Android.bp
index 7281066..49bbad4 100644
--- a/drm/libmediadrm/fuzzer/Android.bp
+++ b/drm/libmediadrm/fuzzer/Android.bp
@@ -35,7 +35,7 @@
static_libs: [
"libmediadrm",
"liblog",
- "resourcemanager_aidl_interface-ndk_platform",
+ "resourcemanager_aidl_interface-ndk",
],
header_libs: [
"libmedia_headers",
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
index 9afd3d7..ec4517d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
@@ -11,4 +11,4 @@
user media
group media mediadrm
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
index c1abe7f..3b48cf2 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
@@ -10,4 +10,4 @@
user media
group media mediadrm
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service-lazy.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service-lazy.clearkey.rc
index 1e0d431..6e64978 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service-lazy.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service-lazy.clearkey.rc
@@ -13,4 +13,4 @@
user media
group media mediadrm
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service.clearkey.rc
index 8130511..e302e1b 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service.clearkey.rc
@@ -11,4 +11,4 @@
user media
group media mediadrm
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service-lazy.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service-lazy.clearkey.rc
index 46aba88..84a63a1 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service-lazy.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service-lazy.clearkey.rc
@@ -15,4 +15,4 @@
user media
group media mediadrm
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service.clearkey.rc
index 8186933..649599e 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service.clearkey.rc
@@ -13,4 +13,4 @@
user media
group media mediadrm
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
diff --git a/include/OWNERS b/include/OWNERS
index d6bd998..88de595 100644
--- a/include/OWNERS
+++ b/include/OWNERS
@@ -1,6 +1,5 @@
elaurent@google.com
-gkasten@google.com
hunga@google.com
jtinker@google.com
lajos@google.com
-marcone@google.com
+essick@google.com
diff --git a/media/OWNERS b/media/OWNERS
index 4cf4870..099729f 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -15,6 +15,7 @@
robertshih@google.com
taklee@google.com
wonsik@google.com
+ytai@google.com
# go/android-fwk-media-solutions for info on areas of ownership.
include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/media/audioserver/Android.bp b/media/audioserver/Android.bp
index be25ffb..e5f9907 100644
--- a/media/audioserver/Android.bp
+++ b/media/audioserver/Android.bp
@@ -25,6 +25,7 @@
],
shared_libs: [
+ "packagemanager_aidl-cpp",
"libaaudioservice",
"libaudioflinger",
"libaudiopolicyservice",
@@ -41,7 +42,6 @@
"libpowermanager",
"libutils",
"libvibrator",
-
],
// TODO check if we still need all of these include directories
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index 8ee1efb..c5ac7f9 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -73,10 +73,8 @@
IPCThreadState::self()->joinThreadPool();
for (;;) {
siginfo_t info;
- int ret = waitid(P_PID, childPid, &info, WEXITED | WSTOPPED | WCONTINUED);
- if (ret == EINTR) {
- continue;
- }
+ int ret = TEMP_FAILURE_RETRY(waitid(P_PID, childPid, &info,
+ WEXITED | WSTOPPED | WCONTINUED));
if (ret < 0) {
break;
}
diff --git a/media/codec2/TEST_MAPPING b/media/codec2/TEST_MAPPING
index 6ac4210..c6728c8 100644
--- a/media/codec2/TEST_MAPPING
+++ b/media/codec2/TEST_MAPPING
@@ -15,13 +15,35 @@
},
{
"exclude-annotation": "android.platform.test.annotations.RequiresDevice"
+ }
+ ]
+ },
+ {
+ "name": "CtsMediaAudioTestCases",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
},
// TODO: b/149314419
{
- "exclude-filter": "android.media.cts.AudioPlaybackCaptureTest"
+ "exclude-filter": "android.media.audio.cts.AudioPlaybackCaptureTest"
},
{
- "exclude-filter": "android.media.cts.AudioRecordTest"
+ "exclude-filter": "android.media.audio.cts.AudioRecordTest"
+ }
+ ]
+ },
+ {
+ "name": "CtsMediaPlayerTestCases",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
}
]
}
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index e8287f9..cc4517d 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -511,7 +511,7 @@
status_t C2SoftAvcDec::initDecoder() {
if (OK != createDecoder()) return UNKNOWN_ERROR;
mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN32(mWidth);
+ mStride = ALIGN128(mWidth);
mSignalledError = false;
resetPlugin();
(void) setNumCores();
@@ -777,20 +777,20 @@
return C2_CORRUPTED;
}
if (mOutBlock &&
- (mOutBlock->width() != ALIGN32(mWidth) || mOutBlock->height() != mHeight)) {
+ (mOutBlock->width() != ALIGN128(mWidth) || mOutBlock->height() != mHeight)) {
mOutBlock.reset();
}
if (!mOutBlock) {
uint32_t format = HAL_PIXEL_FORMAT_YV12;
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
c2_status_t err =
- pool->fetchGraphicBlock(ALIGN32(mWidth), mHeight, format, usage, &mOutBlock);
+ pool->fetchGraphicBlock(ALIGN128(mWidth), mHeight, format, usage, &mOutBlock);
if (err != C2_OK) {
ALOGE("fetchGraphicBlock for Output failed with status %d", err);
return err;
}
ALOGV("provided (%dx%d) required (%dx%d)",
- mOutBlock->width(), mOutBlock->height(), ALIGN32(mWidth), mHeight);
+ mOutBlock->width(), mOutBlock->height(), ALIGN128(mWidth), mHeight);
}
return C2_OK;
@@ -928,7 +928,7 @@
if (0 < ps_decode_op->u4_pic_wd && 0 < ps_decode_op->u4_pic_ht) {
if (mHeaderDecoded == false) {
mHeaderDecoded = true;
- mStride = ALIGN32(ps_decode_op->u4_pic_wd);
+ mStride = ALIGN128(ps_decode_op->u4_pic_wd);
setParams(mStride, IVD_DECODE_FRAME);
}
if (ps_decode_op->u4_pic_wd != mWidth || ps_decode_op->u4_pic_ht != mHeight) {
diff --git a/media/codec2/components/avc/C2SoftAvcDec.h b/media/codec2/components/avc/C2SoftAvcDec.h
index 5c07d29..59d5184 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.h
+++ b/media/codec2/components/avc/C2SoftAvcDec.h
@@ -38,7 +38,7 @@
#define ivdext_ctl_set_num_cores_op_t ih264d_ctl_set_num_cores_op_t
#define ivdext_ctl_get_vui_params_ip_t ih264d_ctl_get_vui_params_ip_t
#define ivdext_ctl_get_vui_params_op_t ih264d_ctl_get_vui_params_op_t
-#define ALIGN32(x) ((((x) + 31) >> 5) << 5)
+#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
#define MAX_NUM_CORES 4
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/components/flac/C2SoftFlacEnc.cpp b/media/codec2/components/flac/C2SoftFlacEnc.cpp
index 6fead3a..182edfb 100644
--- a/media/codec2/components/flac/C2SoftFlacEnc.cpp
+++ b/media/codec2/components/flac/C2SoftFlacEnc.cpp
@@ -439,9 +439,6 @@
}
FLAC__bool ok = FLAC__stream_encoder_finish(mFlacStreamEncoder);
if (!ok) return C2_CORRUPTED;
- mIsFirstFrame = true;
- mAnchorTimeStamp = 0ull;
- mProcessedSamples = 0u;
return C2_OK;
}
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index f857e87..475d863 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -20,6 +20,8 @@
#include <C2Debug.h>
#include <C2PlatformSupport.h>
+#include <Codec2BufferUtils.h>
+#include <Codec2Mapper.h>
#include <SimpleC2Interface.h>
#include <log/log.h>
#include <media/stagefright/foundation/AUtils.h>
@@ -156,6 +158,42 @@
.withSetter(DefaultColorAspectsSetter)
.build());
+ addParameter(
+ DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::input(
+ 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({
+ C2F(mCodedColorAspects, range).inRange(
+ C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mCodedColorAspects, primaries).inRange(
+ C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+ C2F(mCodedColorAspects, transfer).inRange(
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+ C2F(mCodedColorAspects, matrix).inRange(
+ C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+ })
+ .withSetter(CodedColorAspectsSetter)
+ .build());
+
+ addParameter(
+ DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::output(
+ 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({
+ C2F(mColorAspects, range).inRange(
+ C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mColorAspects, primaries).inRange(
+ C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+ C2F(mColorAspects, transfer).inRange(
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+ C2F(mColorAspects, matrix).inRange(
+ C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+ })
+ .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects)
+ .build());
+
// TODO: support more formats?
addParameter(DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
.withConstValue(new C2StreamPixelFormatInfo::output(
@@ -218,6 +256,37 @@
return C2R::Ok();
}
+ static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
+ (void)mayBlock;
+ if (me.v.range > C2Color::RANGE_OTHER) {
+ me.set().range = C2Color::RANGE_OTHER;
+ }
+ if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+ me.set().primaries = C2Color::PRIMARIES_OTHER;
+ }
+ if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+ me.set().transfer = C2Color::TRANSFER_OTHER;
+ }
+ if (me.v.matrix > C2Color::MATRIX_OTHER) {
+ me.set().matrix = C2Color::MATRIX_OTHER;
+ }
+ return C2R::Ok();
+ }
+
+ static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
+ const C2P<C2StreamColorAspectsTuning::output> &def,
+ const C2P<C2StreamColorAspectsInfo::input> &coded) {
+ (void)mayBlock;
+ // take default values for all unspecified fields, and coded values for specified ones
+ me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
+ me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED
+ ? def.v.primaries : coded.v.primaries;
+ me.set().transfer = coded.v.transfer == TRANSFER_UNSPECIFIED
+ ? def.v.transfer : coded.v.transfer;
+ me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix;
+ return C2R::Ok();
+ }
+
static C2R ProfileLevelSetter(
bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
const C2P<C2StreamPictureSizeInfo::output> &size) {
@@ -232,6 +301,10 @@
return mDefaultColorAspects;
}
+ std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() {
+ return mColorAspects;
+ }
+
static C2R Hdr10PlusInfoInputSetter(bool mayBlock,
C2P<C2StreamHdr10PlusInfo::input> &me) {
(void)mayBlock;
@@ -254,6 +327,8 @@
std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
+ std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects;
+ std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput;
std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput;
};
@@ -264,6 +339,7 @@
std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
mIntf(intfImpl),
mCodecCtx(nullptr) {
+ mIsFormatR10G10B10A2Supported = IsFormatR10G10B10A2SupportedForLegacyRendering();
gettimeofday(&mTimeStart, nullptr);
gettimeofday(&mTimeEnd, nullptr);
}
@@ -371,6 +447,10 @@
const std::shared_ptr<C2GraphicBlock> &block) {
std::shared_ptr<C2Buffer> buffer =
createGraphicBuffer(block, C2Rect(mWidth, mHeight));
+ {
+ IntfImpl::Lock lock = mIntf->lock();
+ buffer->setInfo(mIntf->getColorAspects_l());
+ }
auto fillWork = [buffer, index](const std::unique_ptr<C2Work> &work) {
uint32_t flags = 0;
if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
@@ -609,6 +689,38 @@
}
}
+void C2SoftGav1Dec::getVuiParams(const libgav1::DecoderBuffer *buffer) {
+ VuiColorAspects vuiColorAspects;
+ vuiColorAspects.primaries = buffer->color_primary;
+ vuiColorAspects.transfer = buffer->transfer_characteristics;
+ vuiColorAspects.coeffs = buffer->matrix_coefficients;
+ vuiColorAspects.fullRange = buffer->color_range;
+
+ // convert vui aspects to C2 values if changed
+ if (!(vuiColorAspects == mBitstreamColorAspects)) {
+ mBitstreamColorAspects = vuiColorAspects;
+ ColorAspects sfAspects;
+ C2StreamColorAspectsInfo::input codedAspects = { 0u };
+ ColorUtils::convertIsoColorAspectsToCodecAspects(
+ vuiColorAspects.primaries, vuiColorAspects.transfer, vuiColorAspects.coeffs,
+ vuiColorAspects.fullRange, sfAspects);
+ if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) {
+ codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED;
+ }
+ if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) {
+ codedAspects.range = C2Color::RANGE_UNSPECIFIED;
+ }
+ if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) {
+ codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED;
+ }
+ if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) {
+ codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED;
+ }
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures);
+ }
+}
+
bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
const std::unique_ptr<C2Work> &work) {
if (!(work && pool)) return false;
@@ -651,6 +763,7 @@
}
}
+ getVuiParams(buffer);
if (!(buffer->image_format == libgav1::kImageFormatYuv420 ||
buffer->image_format == libgav1::kImageFormatMonochrome400)) {
ALOGE("image_format %d not supported", buffer->image_format);
@@ -666,12 +779,12 @@
uint32_t format = HAL_PIXEL_FORMAT_YV12;
if (buffer->bitdepth == 10) {
IntfImpl::Lock lock = mIntf->lock();
- std::shared_ptr<C2StreamColorAspectsTuning::output> defaultColorAspects =
- mIntf->getDefaultColorAspects_l();
+ std::shared_ptr<C2StreamColorAspectsInfo::output> codedColorAspects =
+ mIntf->getColorAspects_l();
- if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
- defaultColorAspects->matrix == C2Color::MATRIX_BT2020 &&
- defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) {
+ if (codedColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
+ codedColorAspects->matrix == C2Color::MATRIX_BT2020 &&
+ codedColorAspects->transfer == C2Color::TRANSFER_ST2084) {
if (buffer->image_format != libgav1::kImageFormatYuv420) {
ALOGE("Only YUV420 output is supported when targeting RGBA_1010102");
mSignalledError = true;
@@ -679,7 +792,14 @@
work->workletsProcessed = 1u;
return false;
}
- format = HAL_PIXEL_FORMAT_RGBA_1010102;
+ // TODO (b/201787956) For devices that do not support HAL_PIXEL_FORMAT_RGBA_1010102,
+ // HAL_PIXEL_FORMAT_YV12 is used as a temporary work around.
+ if (!mIsFormatR10G10B10A2Supported) {
+ ALOGE("HAL_PIXEL_FORMAT_RGBA_1010102 isn't supported");
+ format = HAL_PIXEL_FORMAT_YV12;
+ } else {
+ format = HAL_PIXEL_FORMAT_RGBA_1010102;
+ }
}
}
C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index 555adc9..f82992d 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -17,7 +17,10 @@
#ifndef ANDROID_C2_SOFT_GAV1_DEC_H_
#define ANDROID_C2_SOFT_GAV1_DEC_H_
+#include <media/stagefright/foundation/ColorUtils.h>
+
#include <SimpleC2Component.h>
+#include <C2Config.h>
#include "libgav1/src/gav1/decoder.h"
#include "libgav1/src/gav1/decoder_settings.h"
@@ -56,10 +59,33 @@
bool mSignalledOutputEos;
bool mSignalledError;
+ // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
+ // converting them to C2 values for each frame
+ struct VuiColorAspects {
+ uint8_t primaries;
+ uint8_t transfer;
+ uint8_t coeffs;
+ uint8_t fullRange;
+
+ // default color aspects
+ VuiColorAspects()
+ : primaries(C2Color::PRIMARIES_UNSPECIFIED),
+ transfer(C2Color::TRANSFER_UNSPECIFIED),
+ coeffs(C2Color::MATRIX_UNSPECIFIED),
+ fullRange(C2Color::RANGE_UNSPECIFIED) { }
+
+ bool operator==(const VuiColorAspects &o) {
+ return primaries == o.primaries && transfer == o.transfer && coeffs == o.coeffs
+ && fullRange == o.fullRange;
+ }
+ } mBitstreamColorAspects;
+
struct timeval mTimeStart; // Time at the start of decode()
struct timeval mTimeEnd; // Time at the end of decode()
+ bool mIsFormatR10G10B10A2Supported;
bool initDecoder();
+ void getVuiParams(const libgav1::DecoderBuffer *buffer);
void destroyDecoder();
void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
const std::shared_ptr<C2GraphicBlock>& block);
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 6bcf3a2..5f5b2ef 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -502,7 +502,7 @@
status_t C2SoftHevcDec::initDecoder() {
if (OK != createDecoder()) return UNKNOWN_ERROR;
mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN32(mWidth);
+ mStride = ALIGN128(mWidth);
mSignalledError = false;
resetPlugin();
(void) setNumCores();
@@ -768,20 +768,20 @@
return C2_CORRUPTED;
}
if (mOutBlock &&
- (mOutBlock->width() != ALIGN32(mWidth) || mOutBlock->height() != mHeight)) {
+ (mOutBlock->width() != ALIGN128(mWidth) || mOutBlock->height() != mHeight)) {
mOutBlock.reset();
}
if (!mOutBlock) {
uint32_t format = HAL_PIXEL_FORMAT_YV12;
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
c2_status_t err =
- pool->fetchGraphicBlock(ALIGN32(mWidth), mHeight, format, usage, &mOutBlock);
+ pool->fetchGraphicBlock(ALIGN128(mWidth), mHeight, format, usage, &mOutBlock);
if (err != C2_OK) {
ALOGE("fetchGraphicBlock for Output failed with status %d", err);
return err;
}
ALOGV("provided (%dx%d) required (%dx%d)",
- mOutBlock->width(), mOutBlock->height(), ALIGN32(mWidth), mHeight);
+ mOutBlock->width(), mOutBlock->height(), ALIGN128(mWidth), mHeight);
}
return C2_OK;
@@ -917,7 +917,7 @@
if (0 < ps_decode_op->u4_pic_wd && 0 < ps_decode_op->u4_pic_ht) {
if (mHeaderDecoded == false) {
mHeaderDecoded = true;
- setParams(ALIGN32(ps_decode_op->u4_pic_wd), IVD_DECODE_FRAME);
+ setParams(ALIGN128(ps_decode_op->u4_pic_wd), IVD_DECODE_FRAME);
}
if (ps_decode_op->u4_pic_wd != mWidth || ps_decode_op->u4_pic_ht != mHeight) {
mWidth = ps_decode_op->u4_pic_wd;
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.h b/media/codec2/components/hevc/C2SoftHevcDec.h
index b9b0a48..b9296e9 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.h
+++ b/media/codec2/components/hevc/C2SoftHevcDec.h
@@ -36,7 +36,7 @@
#define ivdext_ctl_set_num_cores_op_t ihevcd_cxa_ctl_set_num_cores_op_t
#define ivdext_ctl_get_vui_params_ip_t ihevcd_cxa_ctl_get_vui_params_ip_t
#define ivdext_ctl_get_vui_params_op_t ihevcd_cxa_ctl_get_vui_params_op_t
-#define ALIGN32(x) ((((x) + 31) >> 5) << 5)
+#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
#define MAX_NUM_CORES 4
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index 4bc1777..b7a5686 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -245,6 +245,19 @@
})
.withSetter(CodedColorAspectsSetter, mColorAspects)
.build());
+
+ addParameter(
+ DefineParam(mPictureQuantization, C2_PARAMKEY_PICTURE_QUANTIZATION)
+ .withDefault(C2StreamPictureQuantizationTuning::output::AllocShared(
+ 0 /* flexCount */, 0u /* stream */))
+ .withFields({C2F(mPictureQuantization, m.values[0].type_).oneOf(
+ {C2Config::picture_type_t(I_FRAME),
+ C2Config::picture_type_t(P_FRAME),
+ C2Config::picture_type_t(B_FRAME)}),
+ C2F(mPictureQuantization, m.values[0].min).any(),
+ C2F(mPictureQuantization, m.values[0].max).any()})
+ .withSetter(PictureQuantizationSetter)
+ .build());
}
static C2R InputDelaySetter(
@@ -464,9 +477,69 @@
me.set().matrix = coded.v.matrix;
return C2R::Ok();
}
+ static C2R PictureQuantizationSetter(bool mayBlock,
+ C2P<C2StreamPictureQuantizationTuning::output> &me) {
+ (void)mayBlock;
+
+ // these are the ones we're going to set, so want them to default
+ // to the DEFAULT values for the codec
+ int32_t iMin = HEVC_QP_MIN, pMin = HEVC_QP_MIN, bMin = HEVC_QP_MIN;
+ int32_t iMax = HEVC_QP_MAX, pMax = HEVC_QP_MAX, bMax = HEVC_QP_MAX;
+
+ for (size_t i = 0; i < me.v.flexCount(); ++i) {
+ const C2PictureQuantizationStruct &layer = me.v.m.values[i];
+
+ // layerMin is clamped to [HEVC_QP_MIN, layerMax] to avoid error
+ // cases where layer.min > layer.max
+ int32_t layerMax = std::clamp(layer.max, HEVC_QP_MIN, HEVC_QP_MAX);
+ int32_t layerMin = std::clamp(layer.min, HEVC_QP_MIN, layerMax);
+ if (layer.type_ == C2Config::picture_type_t(I_FRAME)) {
+ iMax = layerMax;
+ iMin = layerMin;
+ ALOGV("iMin %d iMax %d", iMin, iMax);
+ } else if (layer.type_ == C2Config::picture_type_t(P_FRAME)) {
+ pMax = layerMax;
+ pMin = layerMin;
+ ALOGV("pMin %d pMax %d", pMin, pMax);
+ } else if (layer.type_ == C2Config::picture_type_t(B_FRAME)) {
+ bMax = layerMax;
+ bMin = layerMin;
+ ALOGV("bMin %d bMax %d", bMin, bMax);
+ }
+ }
+
+ ALOGV("PictureQuantizationSetter(entry): i %d-%d p %d-%d b %d-%d",
+ iMin, iMax, pMin, pMax, bMin, bMax);
+
+ int32_t maxFrameQP = std::min(std::min(iMax, pMax), bMax);
+ int32_t minFrameQP = std::max(std::max(iMin, pMin), bMin);
+ if (minFrameQP > maxFrameQP) {
+ minFrameQP = maxFrameQP;
+ }
+
+ // put them back into the structure
+ for (size_t i = 0; i < me.v.flexCount(); ++i) {
+ const C2PictureQuantizationStruct &layer = me.v.m.values[i];
+
+ if (layer.type_ == C2Config::picture_type_t(I_FRAME) ||
+ layer.type_ == C2Config::picture_type_t(P_FRAME) ||
+ layer.type_ == C2Config::picture_type_t(B_FRAME)) {
+ me.set().m.values[i].max = maxFrameQP;
+ me.set().m.values[i].min = minFrameQP;
+ }
+ }
+
+ ALOGV("PictureQuantizationSetter(exit): i = p = b = %d-%d",
+ minFrameQP, maxFrameQP);
+
+ return C2R::Ok();
+ }
std::shared_ptr<C2StreamColorAspectsInfo::output> getCodedColorAspects_l() {
return mCodedColorAspects;
}
+ std::shared_ptr<C2StreamPictureQuantizationTuning::output> getPictureQuantization_l() const {
+ return mPictureQuantization;
+ }
private:
std::shared_ptr<C2StreamUsageTuning::input> mUsage;
@@ -482,6 +555,7 @@
std::shared_ptr<C2StreamGopTuning::output> mGop;
std::shared_ptr<C2StreamColorAspectsInfo::input> mColorAspects;
std::shared_ptr<C2StreamColorAspectsInfo::output> mCodedColorAspects;
+ std::shared_ptr<C2StreamPictureQuantizationTuning::output> mPictureQuantization;
};
static size_t GetCPUCoreCount() {
@@ -654,12 +728,41 @@
mEncParams.s_coding_tools_prms.i4_max_temporal_layers = 3;
}
- switch (mBitrateMode->value) {
- case C2Config::BITRATE_IGNORE:
- mEncParams.s_config_prms.i4_rate_control_mode = 3;
- mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_frame_qp[0] =
- getQpFromQuality(mQuality->value);
+ // we resolved out-of-bound and unspecified values in PictureQuantizationSetter()
+ // so we can start with defaults that are overridden as needed.
+ int32_t maxFrameQP = mEncParams.s_config_prms.i4_max_frame_qp;
+ int32_t minFrameQP = mEncParams.s_config_prms.i4_min_frame_qp;
+
+ for (size_t i = 0; i < mQpBounds->flexCount(); ++i) {
+ const C2PictureQuantizationStruct &layer = mQpBounds->m.values[i];
+
+ // no need to loop, hevc library takes same range for I/P/B picture type
+ if (layer.type_ == C2Config::picture_type_t(I_FRAME) ||
+ layer.type_ == C2Config::picture_type_t(P_FRAME) ||
+ layer.type_ == C2Config::picture_type_t(B_FRAME)) {
+
+ maxFrameQP = layer.max;
+ minFrameQP = layer.min;
break;
+ }
+ }
+ mEncParams.s_config_prms.i4_max_frame_qp = maxFrameQP;
+ mEncParams.s_config_prms.i4_min_frame_qp = minFrameQP;
+
+ ALOGV("MaxFrameQp: %d MinFrameQp: %d", maxFrameQP, minFrameQP);
+
+ mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_frame_qp[0] =
+ std::clamp(kDefaultInitQP, minFrameQP, maxFrameQP);
+
+ switch (mBitrateMode->value) {
+ case C2Config::BITRATE_IGNORE: {
+ mEncParams.s_config_prms.i4_rate_control_mode = 3;
+ // ensure initial qp values are within our newly configured bounds
+ int32_t frameQp = getQpFromQuality(mQuality->value);
+ mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_frame_qp[0] =
+ std::clamp(frameQp, minFrameQP, maxFrameQP);
+ break;
+ }
case C2Config::BITRATE_CONST:
mEncParams.s_config_prms.i4_rate_control_mode = 5;
break;
@@ -723,6 +826,7 @@
mGop = mIntf->getGop_l();
mRequestSync = mIntf->getRequestSync_l();
mColorAspects = mIntf->getCodedColorAspects_l();
+ mQpBounds = mIntf->getPictureQuantization_l();;
}
c2_status_t status = initEncParams();
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.h b/media/codec2/components/hevc/C2SoftHevcEnc.h
index 9dbf682..4217a8b 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.h
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.h
@@ -42,6 +42,11 @@
#define DEFAULT_B_FRAMES 0
#define DEFAULT_RC_LOOKAHEAD 0
+#define HEVC_QP_MIN 1
+#define HEVC_QP_MAX 51
+
+constexpr int32_t kDefaultInitQP = 32;
+
struct C2SoftHevcEnc : public SimpleC2Component {
class IntfImpl;
@@ -90,6 +95,7 @@
std::shared_ptr<C2StreamGopTuning::output> mGop;
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
+ std::shared_ptr<C2StreamPictureQuantizationTuning::output> mQpBounds;
#ifdef FILE_DUMP_ENABLE
char mInFile[200];
char mOutFile[200];
diff --git a/media/codec2/components/mp3/C2SoftMp3Dec.cpp b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
index e394670..149c6ee 100644
--- a/media/codec2/components/mp3/C2SoftMp3Dec.cpp
+++ b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
@@ -321,6 +321,13 @@
return C2_OK;
}
+static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
+ work->worklets.front()->output.flags = work->input.flags;
+ work->worklets.front()->output.buffers.clear();
+ work->worklets.front()->output.ordinal = work->input.ordinal;
+ work->workletsProcessed = 1u;
+}
+
// TODO: Can overall error checking be improved? As in the check for validity of
// work, pool ptr, work->input.buffers.size() == 1, ...
// TODO: Blind removal of 529 samples from the output may not work. Because
@@ -486,17 +493,17 @@
}
}
- int64_t outTimeStamp = mProcessedSamples * 1000000ll / samplingRate;
- mProcessedSamples += ((outSize - outOffset) / (numChannels * sizeof(int16_t)));
- ALOGV("out buffer attr. offset %d size %d timestamp %" PRId64 " ", outOffset,
- outSize - outOffset, mAnchorTimeStamp + outTimeStamp);
- decodedSizes.clear();
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(
- createLinearBuffer(block, outOffset, outSize - outOffset));
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
+ fillEmptyWork(work);
+ if (samplingRate && numChannels) {
+ int64_t outTimeStamp = mProcessedSamples * 1000000ll / samplingRate;
+ mProcessedSamples += ((outSize - outOffset) / (numChannels * sizeof(int16_t)));
+ ALOGV("out buffer attr. offset %d size %d timestamp %" PRId64 " ", outOffset,
+ outSize - outOffset, mAnchorTimeStamp + outTimeStamp);
+ decodedSizes.clear();
+ work->worklets.front()->output.buffers.push_back(
+ createLinearBuffer(block, outOffset, outSize - outOffset));
+ work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
+ }
if (eos) {
mSignalledOutputEos = true;
ALOGV("signalled EOS");
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index b1cf388..5f9b30b 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -572,7 +572,7 @@
if (OK != createDecoder()) return UNKNOWN_ERROR;
mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN32(mWidth);
+ mStride = ALIGN128(mWidth);
mSignalledError = false;
resetPlugin();
(void) setNumCores();
@@ -845,20 +845,20 @@
return C2_CORRUPTED;
}
if (mOutBlock &&
- (mOutBlock->width() != ALIGN32(mWidth) || mOutBlock->height() != mHeight)) {
+ (mOutBlock->width() != ALIGN128(mWidth) || mOutBlock->height() != mHeight)) {
mOutBlock.reset();
}
if (!mOutBlock) {
uint32_t format = HAL_PIXEL_FORMAT_YV12;
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
c2_status_t err =
- pool->fetchGraphicBlock(ALIGN32(mWidth), mHeight, format, usage, &mOutBlock);
+ pool->fetchGraphicBlock(ALIGN128(mWidth), mHeight, format, usage, &mOutBlock);
if (err != C2_OK) {
ALOGE("fetchGraphicBlock for Output failed with status %d", err);
return err;
}
ALOGV("provided (%dx%d) required (%dx%d)",
- mOutBlock->width(), mOutBlock->height(), ALIGN32(mWidth), mHeight);
+ mOutBlock->width(), mOutBlock->height(), ALIGN128(mWidth), mHeight);
}
return C2_OK;
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
index fd66304a..8a29c14 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
@@ -37,7 +37,7 @@
#define ivdext_ctl_set_num_cores_op_t impeg2d_ctl_set_num_cores_op_t
#define ivdext_ctl_get_seq_info_ip_t impeg2d_ctl_get_seq_info_ip_t
#define ivdext_ctl_get_seq_info_op_t impeg2d_ctl_get_seq_info_op_t
-#define ALIGN32(x) ((((x) + 31) >> 5) << 5)
+#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
#define MAX_NUM_CORES 4
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
index ddd312f..81f4679 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
@@ -228,7 +228,6 @@
const std::shared_ptr<IntfImpl> &intfImpl)
: SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
mIntf(intfImpl),
- mDecHandle(nullptr),
mOutputBuffer{},
mInitialized(false) {
}
@@ -244,9 +243,7 @@
c2_status_t C2SoftMpeg4Dec::onStop() {
if (mInitialized) {
- if (mDecHandle) {
- PVCleanUpVideoDecoder(mDecHandle);
- }
+ PVCleanUpVideoDecoder(&mVideoDecControls);
mInitialized = false;
}
for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
@@ -269,28 +266,15 @@
}
void C2SoftMpeg4Dec::onRelease() {
- if (mInitialized) {
- if (mDecHandle) {
- PVCleanUpVideoDecoder(mDecHandle);
- delete mDecHandle;
- mDecHandle = nullptr;
- }
- mInitialized = false;
- }
+ (void)onStop();
if (mOutBlock) {
mOutBlock.reset();
}
- for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
- if (mOutputBuffer[i]) {
- free(mOutputBuffer[i]);
- mOutputBuffer[i] = nullptr;
- }
- }
}
c2_status_t C2SoftMpeg4Dec::onFlush_sm() {
if (mInitialized) {
- if (PV_TRUE != PVResetVideoDecoder(mDecHandle)) {
+ if (PV_TRUE != PVResetVideoDecoder(&mVideoDecControls)) {
return C2_CORRUPTED;
}
}
@@ -305,14 +289,8 @@
#else
mIsMpeg4 = false;
#endif
- if (!mDecHandle) {
- mDecHandle = new tagvideoDecControls;
- }
- if (!mDecHandle) {
- ALOGE("mDecHandle is null");
- return NO_MEMORY;
- }
- memset(mDecHandle, 0, sizeof(tagvideoDecControls));
+
+ memset(&mVideoDecControls, 0, sizeof(tagvideoDecControls));
/* TODO: bring these values to 352 and 288. It cannot be done as of now
* because, h263 doesn't seem to allow port reconfiguration. In OMX, the
@@ -368,10 +346,6 @@
}
c2_status_t C2SoftMpeg4Dec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
- if (!mDecHandle) {
- ALOGE("not supposed to be here, invalid decoder context");
- return C2_CORRUPTED;
- }
mOutputBufferSize = align(mIntf->getMaxWidth(), 16) * align(mIntf->getMaxHeight(), 16) * 3 / 2;
for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
@@ -402,10 +376,10 @@
bool C2SoftMpeg4Dec::handleResChange(const std::unique_ptr<C2Work> &work) {
uint32_t disp_width, disp_height;
- PVGetVideoDimensions(mDecHandle, (int32 *)&disp_width, (int32 *)&disp_height);
+ PVGetVideoDimensions(&mVideoDecControls, (int32 *)&disp_width, (int32 *)&disp_height);
uint32_t buf_width, buf_height;
- PVGetBufferDimensions(mDecHandle, (int32 *)&buf_width, (int32 *)&buf_height);
+ PVGetBufferDimensions(&mVideoDecControls, (int32 *)&buf_width, (int32 *)&buf_height);
CHECK_LE(disp_width, buf_width);
CHECK_LE(disp_height, buf_height);
@@ -426,13 +400,14 @@
}
if (!mIsMpeg4) {
- PVCleanUpVideoDecoder(mDecHandle);
+ PVCleanUpVideoDecoder(&mVideoDecControls);
uint8_t *vol_data[1]{};
int32_t vol_size = 0;
if (!PVInitVideoDecoder(
- mDecHandle, vol_data, &vol_size, 1, mIntf->getMaxWidth(), mIntf->getMaxHeight(), H263_MODE)) {
+ &mVideoDecControls, vol_data, &vol_size, 1, mIntf->getMaxWidth(),
+ mIntf->getMaxHeight(), H263_MODE)) {
ALOGE("Error in PVInitVideoDecoder H263_MODE while resChanged was set to true");
mSignalledError = true;
work->result = C2_CORRUPTED;
@@ -522,7 +497,7 @@
uint32_t *start_code = (uint32_t *)bitstream;
bool volHeader = *start_code == 0xB0010000;
if (volHeader) {
- PVCleanUpVideoDecoder(mDecHandle);
+ PVCleanUpVideoDecoder(&mVideoDecControls);
mInitialized = false;
}
@@ -537,7 +512,7 @@
}
MP4DecodingMode mode = (mIsMpeg4) ? MPEG4_MODE : H263_MODE;
if (!PVInitVideoDecoder(
- mDecHandle, vol_data, &vol_size, 1,
+ &mVideoDecControls, vol_data, &vol_size, 1,
mIntf->getMaxWidth(), mIntf->getMaxHeight(), mode)) {
ALOGE("PVInitVideoDecoder failed. Unsupported content?");
mSignalledError = true;
@@ -545,7 +520,7 @@
return;
}
mInitialized = true;
- MP4DecodingMode actualMode = PVGetDecBitstreamMode(mDecHandle);
+ MP4DecodingMode actualMode = PVGetDecBitstreamMode(&mVideoDecControls);
if (mode != actualMode) {
ALOGE("Decoded mode not same as actual mode of the decoder");
mSignalledError = true;
@@ -553,7 +528,7 @@
return;
}
- PVSetPostProcType(mDecHandle, 0);
+ PVSetPostProcType(&mVideoDecControls, 0);
if (handleResChange(work)) {
ALOGI("Setting width and height");
C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight);
@@ -590,7 +565,7 @@
return;
}
- uint32_t yFrameSize = sizeof(uint8) * mDecHandle->size;
+ uint32_t yFrameSize = sizeof(uint8) * mVideoDecControls.size;
if (mOutputBufferSize < yFrameSize * 3 / 2){
ALOGE("Too small output buffer: %zu bytes", mOutputBufferSize);
mSignalledError = true;
@@ -599,7 +574,7 @@
}
if (!mFramesConfigured) {
- PVSetReferenceYUV(mDecHandle,mOutputBuffer[1]);
+ PVSetReferenceYUV(&mVideoDecControls,mOutputBuffer[1]);
mFramesConfigured = true;
}
@@ -610,7 +585,7 @@
uint8_t *bitstreamTmp = bitstream;
uint32_t timestamp = workIndex;
if (PVDecodeVopHeader(
- mDecHandle, &bitstreamTmp, ×tamp, &tmpInSize,
+ &mVideoDecControls, &bitstreamTmp, ×tamp, &tmpInSize,
&header_info, &useExtTimestamp,
mOutputBuffer[mNumSamplesOutput & 1]) != PV_TRUE) {
ALOGE("failed to decode vop header.");
@@ -642,7 +617,7 @@
continue;
}
- if (PVDecodeVopBody(mDecHandle, &tmpInSize) != PV_TRUE) {
+ if (PVDecodeVopBody(&mVideoDecControls, &tmpInSize) != PV_TRUE) {
ALOGE("failed to decode video frame.");
mSignalledError = true;
work->result = C2_CORRUPTED;
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.h b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.h
index 716a095..fed04c9 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.h
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.h
@@ -19,8 +19,8 @@
#include <SimpleC2Component.h>
+#include <mp4dec_api.h>
-struct tagvideoDecControls;
namespace android {
@@ -54,7 +54,7 @@
bool handleResChange(const std::unique_ptr<C2Work> &work);
std::shared_ptr<IntfImpl> mIntf;
- tagvideoDecControls *mDecHandle;
+ tagvideoDecControls mVideoDecControls;
std::shared_ptr<C2GraphicBlock> mOutBlock;
uint8_t *mOutputBuffer[kNumOutputBuffers];
size_t mOutputBufferSize;
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
index 3c87531..3bfec66 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
@@ -436,16 +436,18 @@
}
++mNumInputFrames;
- std::unique_ptr<C2StreamInitDataInfo::output> csd =
- C2StreamInitDataInfo::output::AllocUnique(outputSize, 0u);
- if (!csd) {
- ALOGE("CSD allocation failed");
- mSignalledError = true;
- work->result = C2_NO_MEMORY;
- return;
+ if (outputSize) {
+ std::unique_ptr<C2StreamInitDataInfo::output> csd =
+ C2StreamInitDataInfo::output::AllocUnique(outputSize, 0u);
+ if (!csd) {
+ ALOGE("CSD allocation failed");
+ mSignalledError = true;
+ work->result = C2_NO_MEMORY;
+ return;
+ }
+ memcpy(csd->m.value, outPtr, outputSize);
+ work->worklets.front()->output.configUpdate.push_back(std::move(csd));
}
- memcpy(csd->m.value, outPtr, outputSize);
- work->worklets.front()->output.configUpdate.push_back(std::move(csd));
}
// handle dynamic bitrate change
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index 2953d90..2da9d5b 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -25,6 +25,7 @@
#include <C2Debug.h>
#include <C2PlatformSupport.h>
+#include <Codec2BufferUtils.h>
#include <SimpleC2Interface.h>
#include "C2SoftVpxDec.h"
@@ -149,8 +150,16 @@
#else
addParameter(
DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withConstValue(new C2StreamProfileLevelInfo::input(0u,
- C2Config::PROFILE_UNUSED, C2Config::LEVEL_UNUSED))
+ .withDefault(new C2StreamProfileLevelInfo::input(0u,
+ C2Config::PROFILE_VP8_0, C2Config::LEVEL_UNUSED))
+ .withFields({
+ C2F(mProfileLevel, profile).equalTo(
+ PROFILE_VP8_0
+ ),
+ C2F(mProfileLevel, level).equalTo(
+ LEVEL_UNUSED),
+ })
+ .withSetter(ProfileLevelSetter, mSize)
.build());
#endif
@@ -343,6 +352,7 @@
mCodecCtx(nullptr),
mCoreCount(1),
mQueue(new Mutexed<ConversionQueue>) {
+ mIsFormatR10G10B10A2Supported = IsFormatR10G10B10A2SupportedForLegacyRendering();
}
C2SoftVpxDec::~C2SoftVpxDec() {
@@ -796,7 +806,14 @@
if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
defaultColorAspects->matrix == C2Color::MATRIX_BT2020 &&
defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) {
- format = HAL_PIXEL_FORMAT_RGBA_1010102;
+ // TODO (b/201787956) For devices that do not support HAL_PIXEL_FORMAT_RGBA_1010102,
+ // HAL_PIXEL_FORMAT_YV12 is used as a temporary work around.
+ if (!mIsFormatR10G10B10A2Supported) {
+ ALOGE("HAL_PIXEL_FORMAT_RGBA_1010102 isn't supported");
+ format = HAL_PIXEL_FORMAT_YV12;
+ } else {
+ format = HAL_PIXEL_FORMAT_RGBA_1010102;
+ }
}
}
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.h b/media/codec2/components/vpx/C2SoftVpxDec.h
index 2065165..ade162d 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.h
+++ b/media/codec2/components/vpx/C2SoftVpxDec.h
@@ -80,7 +80,7 @@
};
std::shared_ptr<Mutexed<ConversionQueue>> mQueue;
std::vector<sp<ConverterThread>> mConverterThreads;
-
+ bool mIsFormatR10G10B10A2Supported;
status_t initDecoder();
status_t destroyDecoder();
void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work,
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index 7486d27..617769b 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -31,6 +31,255 @@
namespace android {
+C2SoftVpxEnc::IntfImpl::IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
+ : SimpleInterface<void>::BaseParams(
+ helper,
+ COMPONENT_NAME,
+ C2Component::KIND_ENCODER,
+ C2Component::DOMAIN_VIDEO,
+ MEDIA_MIMETYPE_VIDEO) {
+ noPrivateBuffers(); // TODO: account for our buffers here
+ noInputReferences();
+ noOutputReferences();
+ noInputLatency();
+ noTimeStretch();
+ setDerivedInstance(this);
+
+ addParameter(
+ DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
+ .withConstValue(new C2ComponentAttributesSetting(
+ C2Component::ATTRIB_IS_TEMPORAL))
+ .build());
+
+ addParameter(
+ DefineParam(mUsage, C2_PARAMKEY_INPUT_STREAM_USAGE)
+ .withConstValue(new C2StreamUsageTuning::input(
+ 0u, (uint64_t)C2MemoryUsage::CPU_READ))
+ .build());
+
+ addParameter(
+ DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
+ .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
+ .withFields({
+ C2F(mSize, width).inRange(2, 2048, 2),
+ C2F(mSize, height).inRange(2, 2048, 2),
+ })
+ .withSetter(SizeSetter)
+ .build());
+
+ addParameter(
+ DefineParam(mBitrateMode, C2_PARAMKEY_BITRATE_MODE)
+ .withDefault(new C2StreamBitrateModeTuning::output(
+ 0u, C2Config::BITRATE_VARIABLE))
+ .withFields({
+ C2F(mBitrateMode, value).oneOf({
+ C2Config::BITRATE_CONST, C2Config::BITRATE_VARIABLE })
+ })
+ .withSetter(
+ Setter<decltype(*mBitrateMode)>::StrictValueWithNoDeps)
+ .build());
+
+ addParameter(
+ DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
+ .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
+ // TODO: More restriction?
+ .withFields({C2F(mFrameRate, value).greaterThan(0.)})
+ .withSetter(
+ Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
+ .build());
+
+ addParameter(
+ DefineParam(mLayering, C2_PARAMKEY_TEMPORAL_LAYERING)
+ .withDefault(C2StreamTemporalLayeringTuning::output::AllocShared(0u, 0, 0, 0))
+ .withFields({
+ C2F(mLayering, m.layerCount).inRange(0, 4),
+ C2F(mLayering, m.bLayerCount).inRange(0, 0),
+ C2F(mLayering, m.bitrateRatios).inRange(0., 1.)
+ })
+ .withSetter(LayeringSetter)
+ .build());
+
+ addParameter(
+ DefineParam(mSyncFramePeriod, C2_PARAMKEY_SYNC_FRAME_INTERVAL)
+ .withDefault(new C2StreamSyncFrameIntervalTuning::output(0u, 1000000))
+ .withFields({C2F(mSyncFramePeriod, value).any()})
+ .withSetter(Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
+ .build());
+
+ addParameter(
+ DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
+ .withDefault(new C2StreamBitrateInfo::output(0u, 64000))
+ .withFields({C2F(mBitrate, value).inRange(4096, 40000000)})
+ .withSetter(BitrateSetter)
+ .build());
+
+ addParameter(
+ DefineParam(mIntraRefresh, C2_PARAMKEY_INTRA_REFRESH)
+ .withConstValue(new C2StreamIntraRefreshTuning::output(
+ 0u, C2Config::INTRA_REFRESH_DISABLED, 0.))
+ .build());
+#ifdef VP9
+ addParameter(
+ DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+ .withDefault(new C2StreamProfileLevelInfo::output(
+ 0u, PROFILE_VP9_0, LEVEL_VP9_4_1))
+ .withFields({
+ C2F(mProfileLevel, profile).equalTo(
+ PROFILE_VP9_0
+ ),
+ C2F(mProfileLevel, level).equalTo(
+ LEVEL_VP9_4_1),
+ })
+ .withSetter(ProfileLevelSetter)
+ .build());
+#else
+ addParameter(
+ DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+ .withDefault(new C2StreamProfileLevelInfo::output(
+ 0u, PROFILE_VP8_0, LEVEL_UNUSED))
+ .withFields({
+ C2F(mProfileLevel, profile).equalTo(
+ PROFILE_VP8_0
+ ),
+ C2F(mProfileLevel, level).equalTo(
+ LEVEL_UNUSED),
+ })
+ .withSetter(ProfileLevelSetter)
+ .build());
+#endif
+ addParameter(
+ DefineParam(mRequestSync, C2_PARAMKEY_REQUEST_SYNC_FRAME)
+ .withDefault(new C2StreamRequestSyncFrameTuning::output(0u, C2_FALSE))
+ .withFields({C2F(mRequestSync, value).oneOf({ C2_FALSE, C2_TRUE }) })
+ .withSetter(Setter<decltype(*mRequestSync)>::NonStrictValueWithNoDeps)
+ .build());
+
+ addParameter(
+ DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::input(
+ 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({
+ C2F(mColorAspects, range).inRange(
+ C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mColorAspects, primaries).inRange(
+ C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+ C2F(mColorAspects, transfer).inRange(
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+ C2F(mColorAspects, matrix).inRange(
+ C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+ })
+ .withSetter(ColorAspectsSetter)
+ .build());
+
+ addParameter(
+ DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::output(
+ 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({
+ C2F(mCodedColorAspects, range).inRange(
+ C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mCodedColorAspects, primaries).inRange(
+ C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+ C2F(mCodedColorAspects, transfer).inRange(
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+ C2F(mCodedColorAspects, matrix).inRange(
+ C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+ })
+ .withSetter(CodedColorAspectsSetter, mColorAspects)
+ .build());
+}
+
+C2R C2SoftVpxEnc::IntfImpl::BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me) {
+ (void)mayBlock;
+ C2R res = C2R::Ok();
+ if (me.v.value < 4096) {
+ me.set().value = 4096;
+ }
+ return res;
+}
+
+C2R C2SoftVpxEnc::IntfImpl::SizeSetter(bool mayBlock,
+ const C2P<C2StreamPictureSizeInfo::input>& oldMe,
+ C2P<C2StreamPictureSizeInfo::input>& me) {
+ (void)mayBlock;
+ C2R res = C2R::Ok();
+ if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
+ res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
+ me.set().width = oldMe.v.width;
+ }
+ if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
+ res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
+ me.set().height = oldMe.v.height;
+ }
+ return res;
+}
+
+C2R C2SoftVpxEnc::IntfImpl::ProfileLevelSetter(bool mayBlock,
+ C2P<C2StreamProfileLevelInfo::output>& me) {
+ (void)mayBlock;
+ if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
+ me.set().profile = PROFILE_VP9_0;
+ }
+ if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
+ me.set().level = LEVEL_VP9_4_1;
+ }
+ return C2R::Ok();
+}
+
+C2R C2SoftVpxEnc::IntfImpl::LayeringSetter(bool mayBlock,
+ C2P<C2StreamTemporalLayeringTuning::output>& me) {
+ (void)mayBlock;
+ C2R res = C2R::Ok();
+ if (me.v.m.layerCount > 4) {
+ me.set().m.layerCount = 4;
+ }
+ me.set().m.bLayerCount = 0;
+ // ensure ratios are monotonic and clamped between 0 and 1
+ for (size_t ix = 0; ix < me.v.flexCount(); ++ix) {
+ me.set().m.bitrateRatios[ix] = c2_clamp(
+ ix > 0 ? me.v.m.bitrateRatios[ix - 1] : 0, me.v.m.bitrateRatios[ix], 1.);
+ }
+ ALOGI("setting temporal layering %u + %u", me.v.m.layerCount, me.v.m.bLayerCount);
+ return res;
+}
+
+uint32_t C2SoftVpxEnc::IntfImpl::getSyncFramePeriod() const {
+ if (mSyncFramePeriod->value < 0 || mSyncFramePeriod->value == INT64_MAX) {
+ return 0;
+ }
+ double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
+ return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
+}
+C2R C2SoftVpxEnc::IntfImpl::ColorAspectsSetter(bool mayBlock,
+ C2P<C2StreamColorAspectsInfo::input>& me) {
+ (void)mayBlock;
+ if (me.v.range > C2Color::RANGE_OTHER) {
+ me.set().range = C2Color::RANGE_OTHER;
+ }
+ if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+ me.set().primaries = C2Color::PRIMARIES_OTHER;
+ }
+ if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+ me.set().transfer = C2Color::TRANSFER_OTHER;
+ }
+ if (me.v.matrix > C2Color::MATRIX_OTHER) {
+ me.set().matrix = C2Color::MATRIX_OTHER;
+ }
+ return C2R::Ok();
+}
+C2R C2SoftVpxEnc::IntfImpl::CodedColorAspectsSetter(
+ bool mayBlock, C2P<C2StreamColorAspectsInfo::output>& me,
+ const C2P<C2StreamColorAspectsInfo::input>& coded) {
+ (void)mayBlock;
+ me.set().range = coded.v.range;
+ me.set().primaries = coded.v.primaries;
+ me.set().transfer = coded.v.transfer;
+ me.set().matrix = coded.v.matrix;
+ return C2R::Ok();
+}
+
#if 0
static size_t getCpuCoreCount() {
long cpuCoreCount = 1;
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.h b/media/codec2/components/vpx/C2SoftVpxEnc.h
index c98b802..e296c8f 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.h
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.h
@@ -237,245 +237,38 @@
class C2SoftVpxEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : SimpleInterface<void>::BaseParams(
- helper,
- COMPONENT_NAME,
- C2Component::KIND_ENCODER,
- C2Component::DOMAIN_VIDEO,
- MEDIA_MIMETYPE_VIDEO) {
- noPrivateBuffers(); // TODO: account for our buffers here
- noInputReferences();
- noOutputReferences();
- noInputLatency();
- noTimeStretch();
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
- .withConstValue(new C2ComponentAttributesSetting(
- C2Component::ATTRIB_IS_TEMPORAL))
- .build());
-
- addParameter(
- DefineParam(mUsage, C2_PARAMKEY_INPUT_STREAM_USAGE)
- .withConstValue(new C2StreamUsageTuning::input(
- 0u, (uint64_t)C2MemoryUsage::CPU_READ))
- .build());
-
- addParameter(
- DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
- .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(2, 2048, 2),
- C2F(mSize, height).inRange(2, 2048, 2),
- })
- .withSetter(SizeSetter)
- .build());
-
- addParameter(
- DefineParam(mBitrateMode, C2_PARAMKEY_BITRATE_MODE)
- .withDefault(new C2StreamBitrateModeTuning::output(
- 0u, C2Config::BITRATE_VARIABLE))
- .withFields({
- C2F(mBitrateMode, value).oneOf({
- C2Config::BITRATE_CONST, C2Config::BITRATE_VARIABLE })
- })
- .withSetter(
- Setter<decltype(*mBitrateMode)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
- .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
- // TODO: More restriction?
- .withFields({C2F(mFrameRate, value).greaterThan(0.)})
- .withSetter(
- Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mLayering, C2_PARAMKEY_TEMPORAL_LAYERING)
- .withDefault(C2StreamTemporalLayeringTuning::output::AllocShared(0u, 0, 0, 0))
- .withFields({
- C2F(mLayering, m.layerCount).inRange(0, 4),
- C2F(mLayering, m.bLayerCount).inRange(0, 0),
- C2F(mLayering, m.bitrateRatios).inRange(0., 1.)
- })
- .withSetter(LayeringSetter)
- .build());
-
- addParameter(
- DefineParam(mSyncFramePeriod, C2_PARAMKEY_SYNC_FRAME_INTERVAL)
- .withDefault(new C2StreamSyncFrameIntervalTuning::output(0u, 1000000))
- .withFields({C2F(mSyncFramePeriod, value).any()})
- .withSetter(Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
- .withDefault(new C2StreamBitrateInfo::output(0u, 64000))
- .withFields({C2F(mBitrate, value).inRange(4096, 40000000)})
- .withSetter(BitrateSetter)
- .build());
-
- addParameter(
- DefineParam(mIntraRefresh, C2_PARAMKEY_INTRA_REFRESH)
- .withConstValue(new C2StreamIntraRefreshTuning::output(
- 0u, C2Config::INTRA_REFRESH_DISABLED, 0.))
- .build());
-
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::output(
- 0u, PROFILE_VP9_0, LEVEL_VP9_4_1))
- .withFields({
- C2F(mProfileLevel, profile).equalTo(
- PROFILE_VP9_0
- ),
- C2F(mProfileLevel, level).equalTo(
- LEVEL_VP9_4_1),
- })
- .withSetter(ProfileLevelSetter)
- .build());
-
- addParameter(
- DefineParam(mRequestSync, C2_PARAMKEY_REQUEST_SYNC_FRAME)
- .withDefault(new C2StreamRequestSyncFrameTuning::output(0u, C2_FALSE))
- .withFields({C2F(mRequestSync, value).oneOf({ C2_FALSE, C2_TRUE }) })
- .withSetter(Setter<decltype(*mRequestSync)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsInfo::input(
- 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(ColorAspectsSetter)
- .build());
-
- addParameter(
- DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsInfo::output(
- 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mCodedColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mCodedColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mCodedColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mCodedColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(CodedColorAspectsSetter, mColorAspects)
- .build());
- }
-
- static C2R BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (me.v.value <= 4096) {
- me.set().value = 4096;
- }
- return res;
- }
+ explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper);
+ static C2R BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me);
static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::input> &oldMe,
- C2P<C2StreamPictureSizeInfo::input> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
- me.set().width = oldMe.v.width;
- }
- if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
- me.set().height = oldMe.v.height;
- }
- return res;
- }
+ C2P<C2StreamPictureSizeInfo::input> &me);
static C2R ProfileLevelSetter(
bool mayBlock,
- C2P<C2StreamProfileLevelInfo::output> &me) {
- (void)mayBlock;
- if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
- me.set().profile = PROFILE_VP9_0;
- }
- if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
- me.set().level = LEVEL_VP9_4_1;
- }
- return C2R::Ok();
- }
+ C2P<C2StreamProfileLevelInfo::output> &me);
- static C2R LayeringSetter(bool mayBlock, C2P<C2StreamTemporalLayeringTuning::output>& me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (me.v.m.layerCount > 4) {
- me.set().m.layerCount = 4;
- }
- me.set().m.bLayerCount = 0;
- // ensure ratios are monotonic and clamped between 0 and 1
- for (size_t ix = 0; ix < me.v.flexCount(); ++ix) {
- me.set().m.bitrateRatios[ix] = c2_clamp(
- ix > 0 ? me.v.m.bitrateRatios[ix - 1] : 0, me.v.m.bitrateRatios[ix], 1.);
- }
- ALOGI("setting temporal layering %u + %u", me.v.m.layerCount, me.v.m.bLayerCount);
- return res;
- }
+ static C2R LayeringSetter(bool mayBlock, C2P<C2StreamTemporalLayeringTuning::output>& me);
// unsafe getters
std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
- std::shared_ptr<C2StreamIntraRefreshTuning::output> getIntraRefresh_l() const { return mIntraRefresh; }
+ std::shared_ptr<C2StreamIntraRefreshTuning::output> getIntraRefresh_l() const {
+ return mIntraRefresh;
+ }
std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const { return mFrameRate; }
std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const { return mBitrate; }
- std::shared_ptr<C2StreamBitrateModeTuning::output> getBitrateMode_l() const { return mBitrateMode; }
- std::shared_ptr<C2StreamRequestSyncFrameTuning::output> getRequestSync_l() const { return mRequestSync; }
- std::shared_ptr<C2StreamTemporalLayeringTuning::output> getTemporalLayers_l() const { return mLayering; }
- uint32_t getSyncFramePeriod() const {
- if (mSyncFramePeriod->value < 0 || mSyncFramePeriod->value == INT64_MAX) {
- return 0;
- }
- double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
- return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
+ std::shared_ptr<C2StreamBitrateModeTuning::output> getBitrateMode_l() const {
+ return mBitrateMode;
}
- static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
- (void)mayBlock;
- if (me.v.range > C2Color::RANGE_OTHER) {
- me.set().range = C2Color::RANGE_OTHER;
- }
- if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
- me.set().primaries = C2Color::PRIMARIES_OTHER;
- }
- if (me.v.transfer > C2Color::TRANSFER_OTHER) {
- me.set().transfer = C2Color::TRANSFER_OTHER;
- }
- if (me.v.matrix > C2Color::MATRIX_OTHER) {
- me.set().matrix = C2Color::MATRIX_OTHER;
- }
- return C2R::Ok();
+ std::shared_ptr<C2StreamRequestSyncFrameTuning::output> getRequestSync_l() const {
+ return mRequestSync;
}
+ std::shared_ptr<C2StreamTemporalLayeringTuning::output> getTemporalLayers_l() const {
+ return mLayering;
+ }
+ uint32_t getSyncFramePeriod() const;
+ static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me);
static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
- const C2P<C2StreamColorAspectsInfo::input> &coded) {
- (void)mayBlock;
- me.set().range = coded.v.range;
- me.set().primaries = coded.v.primaries;
- me.set().transfer = coded.v.transfer;
- me.set().matrix = coded.v.matrix;
- return C2R::Ok();
- }
+ const C2P<C2StreamColorAspectsInfo::input> &coded);
private:
std::shared_ptr<C2StreamUsageTuning::input> mUsage;
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 2cc7ab7..feaa98c 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -1673,7 +1673,7 @@
SYNC_FRAME = (1 << 0), ///< sync frame, e.g. IDR
I_FRAME = (1 << 1), ///< intra frame that is completely encoded
P_FRAME = (1 << 2), ///< inter predicted frame from previous frames
- B_FRAME = (1 << 3), ///< backward predicted (out-of-order) frame
+ B_FRAME = (1 << 3), ///< bidirectional predicted (out-of-order) frame
)
/**
diff --git a/media/codec2/fuzzer/C2Fuzzer.cpp b/media/codec2/fuzzer/C2Fuzzer.cpp
index 51e1013..e469d8b 100644
--- a/media/codec2/fuzzer/C2Fuzzer.cpp
+++ b/media/codec2/fuzzer/C2Fuzzer.cpp
@@ -194,12 +194,12 @@
}
std::vector<C2Param*> configParams;
+ C2StreamPictureSizeInfo::input inputSize(0u, kWidthOfVideo, kHeightOfVideo);
+ C2StreamSampleRateInfo::output sampleRateInfo(0u, kSamplingRateOfAudio);
+ C2StreamChannelCountInfo::output channelCountInfo(0u, kChannelsOfAudio);
if (domain.value == DOMAIN_VIDEO) {
- C2StreamPictureSizeInfo::input inputSize(0u, kWidthOfVideo, kHeightOfVideo);
configParams.push_back(&inputSize);
} else if (domain.value == DOMAIN_AUDIO) {
- C2StreamSampleRateInfo::output sampleRateInfo(0u, kSamplingRateOfAudio);
- C2StreamChannelCountInfo::output channelCountInfo(0u, kChannelsOfAudio);
configParams.push_back(&sampleRateInfo);
configParams.push_back(&channelCountInfo);
}
@@ -239,17 +239,17 @@
}
void Codec2Fuzzer::decodeFrames(const uint8_t* data, size_t size) {
- mBufferSource = new BufferSource(data, size);
- if (!mBufferSource) {
+ std::unique_ptr<BufferSource> bufferSource = std::make_unique<BufferSource>(data, size);
+ if (!bufferSource) {
return;
}
- mBufferSource->parse();
+ bufferSource->parse();
c2_status_t status = C2_OK;
size_t numFrames = 0;
- while (!mBufferSource->isEos()) {
+ while (!bufferSource->isEos()) {
uint8_t* frame = nullptr;
size_t frameSize = 0;
- FrameData frameData = mBufferSource->getFrame();
+ FrameData frameData = bufferSource->getFrame();
frame = std::get<0>(frameData);
frameSize = std::get<1>(frameData);
@@ -298,7 +298,6 @@
mConditionalVariable.wait_for(waitForDecodeComplete, kC2FuzzerTimeOut, [this] { return mEos; });
std::list<std::unique_ptr<C2Work>> c2flushedWorks;
mComponent->flush_sm(C2Component::FLUSH_COMPONENT, &c2flushedWorks);
- delete mBufferSource;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/media/codec2/fuzzer/C2Fuzzer.h b/media/codec2/fuzzer/C2Fuzzer.h
index d5ac81a..da76885 100644
--- a/media/codec2/fuzzer/C2Fuzzer.h
+++ b/media/codec2/fuzzer/C2Fuzzer.h
@@ -104,7 +104,6 @@
static constexpr size_t kMarkerSuffixSize = 3;
};
- BufferSource* mBufferSource;
bool mEos = false;
C2BlockPool::local_id_t mBlockPoolId;
diff --git a/media/codec2/hidl/1.0/vts/.clang-format b/media/codec2/hidl/1.0/vts/.clang-format
deleted file mode 120000
index 136279c..0000000
--- a/media/codec2/hidl/1.0/vts/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../../build/soong/scripts/system-clang-format
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/OWNERS b/media/codec2/hidl/1.0/vts/OWNERS
index dbe89cf..32b11b8 100644
--- a/media/codec2/hidl/1.0/vts/OWNERS
+++ b/media/codec2/hidl/1.0/vts/OWNERS
@@ -1,8 +1,5 @@
+# Bug component: 25690
# Media team
lajos@google.com
-pawin@google.com
taklee@google.com
wonsik@google.com
-
-# VTS team
-dshi@google.com
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
index 9e3a823..d47ef67 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
@@ -465,6 +465,11 @@
if (mMime.find("raw") != std::string::npos) {
bitStreamInfo[0] = 8000;
bitStreamInfo[1] = 1;
+ } else if ((mMime.find("g711-alaw") != std::string::npos) ||
+ (mMime.find("g711-mlaw") != std::string::npos)) {
+ // g711 test data is all 1-channel and has no embedded config info.
+ bitStreamInfo[0] = 8000;
+ bitStreamInfo[1] = 1;
} else {
ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mMime, bitStreamInfo));
}
diff --git a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
index ffec897..275a721 100644
--- a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
@@ -61,6 +61,7 @@
public:
virtual void SetUp() override {
getParams();
+ mDisableTest = false;
mEos = false;
mClient = android::Codec2Client::CreateFromService(mInstanceName.c_str());
ASSERT_NE(mClient, nullptr);
@@ -73,6 +74,14 @@
for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
mWorkQueue.emplace_back(new C2Work);
}
+
+ C2SecureModeTuning secureModeTuning{};
+ mComponent->query({&secureModeTuning}, {}, C2_MAY_BLOCK, nullptr);
+ if (secureModeTuning.value != C2Config::SM_UNPROTECTED) {
+ mDisableTest = true;
+ }
+
+ if (mDisableTest) std::cout << "[ WARN ] Test Disabled \n";
}
virtual void TearDown() override {
@@ -105,6 +114,7 @@
std::string mInstanceName;
std::string mComponentName;
bool mEos;
+ bool mDisableTest;
std::mutex mQueueLock;
std::condition_variable mQueueCondition;
std::list<std::unique_ptr<C2Work>> mWorkQueue;
@@ -324,6 +334,7 @@
};
TEST_P(Codec2ComponentInputTests, InputBufferTest) {
+ if (mDisableTest) GTEST_SKIP() << "Test is disabled";
description("Tests for different inputs");
uint32_t flags = std::get<2>(GetParam());
diff --git a/media/codec2/hidl/plugin/FilterWrapper.cpp b/media/codec2/hidl/plugin/FilterWrapper.cpp
index 70c63f2..b6024ff 100644
--- a/media/codec2/hidl/plugin/FilterWrapper.cpp
+++ b/media/codec2/hidl/plugin/FilterWrapper.cpp
@@ -430,6 +430,10 @@
LOG(DEBUG) << "WrappedDecoderInterface: FilterWrapper not found";
return C2_OK;
}
+ if (!filterWrapper->isFilteringEnabled(next)) {
+ LOG(VERBOSE) << "WrappedDecoderInterface: filtering not enabled";
+ return C2_OK;
+ }
std::vector<std::unique_ptr<C2Param>> params;
c2_status_t err = filterWrapper->queryParamsForPreviousComponent(next, ¶ms);
if (err != C2_OK) {
diff --git a/media/codec2/hidl/services/Android.bp b/media/codec2/hidl/services/Android.bp
index bb9f51f..b36e80a 100644
--- a/media/codec2/hidl/services/Android.bp
+++ b/media/codec2/hidl/services/Android.bp
@@ -52,7 +52,7 @@
// minijail is used to protect against unexpected system calls.
shared_libs: [
- "libavservices_minijail_vendor",
+ "libavservices_minijail",
"libbinder",
],
required: ["android.hardware.media.c2@1.2-default-seccomp_policy"],
diff --git a/media/codec2/hidl/services/android.hardware.media.c2@1.2-default-service.rc b/media/codec2/hidl/services/android.hardware.media.c2@1.2-default-service.rc
index 03f6e3d..12da593 100644
--- a/media/codec2/hidl/services/android.hardware.media.c2@1.2-default-service.rc
+++ b/media/codec2/hidl/services/android.hardware.media.c2@1.2-default-service.rc
@@ -3,5 +3,5 @@
user mediacodec
group camera mediadrm drmrpc
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 82460c9..44a2c5b 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1332,8 +1332,8 @@
}
}
- // set channel-mask
if (config->mDomain & Config::IS_AUDIO) {
+ // set channel-mask
int32_t mask;
if (msg->findInt32(KEY_CHANNEL_MASK, &mask)) {
if (config->mDomain & Config::IS_ENCODER) {
@@ -1342,6 +1342,15 @@
config->mOutputFormat->setInt32(KEY_CHANNEL_MASK, mask);
}
}
+
+ // set PCM encoding
+ int32_t pcmEncoding = kAudioEncodingPcm16bit;
+ msg->findInt32(KEY_PCM_ENCODING, &pcmEncoding);
+ if (encoder) {
+ config->mInputFormat->setInt32("android._config-pcm-encoding", pcmEncoding);
+ } else {
+ config->mOutputFormat->setInt32("android._config-pcm-encoding", pcmEncoding);
+ }
}
std::unique_ptr<C2Param> colorTransferRequestParam;
@@ -1421,6 +1430,10 @@
}
}
+ if (config->mTunneled) {
+ config->mOutputFormat->setInt32("android._tunneled", 1);
+ }
+
ALOGD("setup formats input: %s",
config->mInputFormat->debugString().c_str());
ALOGD("setup formats output: %s",
@@ -1896,9 +1909,11 @@
{
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
+ sp<ANativeWindow> nativeWindow = static_cast<ANativeWindow *>(surface.get());
+ status_t err = OK;
+
if (config->mTunneled && config->mSidebandHandle != nullptr) {
- sp<ANativeWindow> nativeWindow = static_cast<ANativeWindow *>(surface.get());
- status_t err = native_window_set_sideband_stream(
+ err = native_window_set_sideband_stream(
nativeWindow.get(),
const_cast<native_handle_t *>(config->mSidebandHandle->handle()));
if (err != OK) {
@@ -1906,6 +1921,15 @@
nativeWindow.get(), config->mSidebandHandle->handle(), err);
return err;
}
+ } else {
+ // Explicitly reset the sideband handle of the window for
+ // non-tunneled video in case the window was previously used
+ // for a tunneled video playback.
+ err = native_window_set_sideband_stream(nativeWindow.get(), nullptr);
+ if (err != OK) {
+ ALOGE("native_window_set_sideband_stream(nullptr) failed! (err %d).", err);
+ return err;
+ }
}
}
return mChannel->setSurface(surface);
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 307396b..0de0b77 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -254,7 +254,7 @@
bool released = input->buffers->releaseBuffer(buffer, nullptr, true);
ALOGV("[%s] queueInputBuffer: buffer copied; %sreleased",
mName, released ? "" : "not ");
- buffer.clear();
+ buffer = copy;
} else {
ALOGW("[%s] queueInputBuffer: failed to copy a buffer; this may cause input "
"buffer starvation on component.", mName);
@@ -282,6 +282,12 @@
}
}
} else if (eos) {
+ Mutexed<Input>::Locked input(mInput);
+ if (input->frameReassembler) {
+ usesFrameReassembler = true;
+ // drain any pending items with eos
+ input->frameReassembler.process(buffer, &items);
+ }
flags |= C2FrameData::FLAG_END_OF_STREAM;
}
if (usesFrameReassembler) {
@@ -341,10 +347,10 @@
} else {
Mutexed<Input>::Locked input(mInput);
bool released = false;
- if (buffer) {
- released = input->buffers->releaseBuffer(buffer, nullptr, true);
- } else if (copy) {
+ if (copy) {
released = input->extraBuffers.releaseSlot(copy, nullptr, true);
+ } else if (buffer) {
+ released = input->buffers->releaseBuffer(buffer, nullptr, true);
}
ALOGV("[%s] queueInputBuffer: buffer%s %sreleased",
mName, (buffer == nullptr) ? "(copy)" : "", released ? "" : "not ");
@@ -1382,6 +1388,12 @@
}
}
}
+
+ int32_t tunneled = 0;
+ if (!outputFormat->findInt32("android._tunneled", &tunneled)) {
+ tunneled = 0;
+ }
+ mTunneled = (tunneled != 0);
}
// Set up pipeline control. This has to be done after mInputBuffers and
@@ -1455,6 +1467,16 @@
std::list<std::unique_ptr<C2Work>> flushedConfigs;
mFlushedConfigs.lock()->swap(flushedConfigs);
if (!flushedConfigs.empty()) {
+ {
+ Mutexed<PipelineWatcher>::Locked watcher(mPipelineWatcher);
+ PipelineWatcher::Clock::time_point now = PipelineWatcher::Clock::now();
+ for (const std::unique_ptr<C2Work> &work : flushedConfigs) {
+ watcher->onWorkQueued(
+ work->input.ordinal.frameIndex.peeku(),
+ std::vector(work->input.buffers),
+ now);
+ }
+ }
err = mComponent->queue(&flushedConfigs);
if (err != C2_OK) {
ALOGW("[%s] Error while queueing a flushed config", mName);
@@ -1521,41 +1543,45 @@
setDescrambler(nullptr);
}
-
void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
ALOGV("[%s] flush", mName);
- std::vector<uint64_t> indices;
std::list<std::unique_ptr<C2Work>> configs;
mInput.lock()->lastFlushIndex = mFrameIndex.load(std::memory_order_relaxed);
- for (const std::unique_ptr<C2Work> &work : flushedWork) {
- indices.push_back(work->input.ordinal.frameIndex.peeku());
- if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
- continue;
+ {
+ Mutexed<PipelineWatcher>::Locked watcher(mPipelineWatcher);
+ for (const std::unique_ptr<C2Work> &work : flushedWork) {
+ uint64_t frameIndex = work->input.ordinal.frameIndex.peeku();
+ if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
+ watcher->onWorkDone(frameIndex);
+ continue;
+ }
+ if (work->input.buffers.empty()
+ || work->input.buffers.front() == nullptr
+ || work->input.buffers.front()->data().linearBlocks().empty()) {
+ ALOGD("[%s] no linear codec config data found", mName);
+ watcher->onWorkDone(frameIndex);
+ continue;
+ }
+ std::unique_ptr<C2Work> copy(new C2Work);
+ copy->input.flags = C2FrameData::flags_t(
+ work->input.flags | C2FrameData::FLAG_DROP_FRAME);
+ copy->input.ordinal = work->input.ordinal;
+ copy->input.ordinal.frameIndex = mFrameIndex++;
+ for (size_t i = 0; i < work->input.buffers.size(); ++i) {
+ copy->input.buffers.push_back(watcher->onInputBufferReleased(frameIndex, i));
+ }
+ for (const std::unique_ptr<C2Param> ¶m : work->input.configUpdate) {
+ copy->input.configUpdate.push_back(C2Param::Copy(*param));
+ }
+ copy->input.infoBuffers.insert(
+ copy->input.infoBuffers.begin(),
+ work->input.infoBuffers.begin(),
+ work->input.infoBuffers.end());
+ copy->worklets.emplace_back(new C2Worklet);
+ configs.push_back(std::move(copy));
+ watcher->onWorkDone(frameIndex);
+ ALOGV("[%s] stashed flushed codec config data", mName);
}
- if (work->input.buffers.empty()
- || work->input.buffers.front() == nullptr
- || work->input.buffers.front()->data().linearBlocks().empty()) {
- ALOGD("[%s] no linear codec config data found", mName);
- continue;
- }
- std::unique_ptr<C2Work> copy(new C2Work);
- copy->input.flags = C2FrameData::flags_t(work->input.flags | C2FrameData::FLAG_DROP_FRAME);
- copy->input.ordinal = work->input.ordinal;
- copy->input.ordinal.frameIndex = mFrameIndex++;
- copy->input.buffers.insert(
- copy->input.buffers.begin(),
- work->input.buffers.begin(),
- work->input.buffers.end());
- for (const std::unique_ptr<C2Param> ¶m : work->input.configUpdate) {
- copy->input.configUpdate.push_back(C2Param::Copy(*param));
- }
- copy->input.infoBuffers.insert(
- copy->input.infoBuffers.begin(),
- work->input.infoBuffers.begin(),
- work->input.infoBuffers.end());
- copy->worklets.emplace_back(new C2Worklet);
- configs.push_back(std::move(copy));
- ALOGV("[%s] stashed flushed codec config data", mName);
}
mFlushedConfigs.lock()->swap(configs);
{
@@ -1570,12 +1596,6 @@
output->buffers->flushStash();
}
}
- {
- Mutexed<PipelineWatcher>::Locked watcher(mPipelineWatcher);
- for (uint64_t index : indices) {
- watcher->onWorkDone(index);
- }
- }
}
void CCodecBufferChannel::onWorkDone(
@@ -1891,10 +1911,21 @@
}
}
+ bool drop = false;
+ if (worklet->output.flags & C2FrameData::FLAG_DROP_FRAME) {
+ ALOGV("[%s] onWorkDone: drop buffer but keep metadata", mName);
+ drop = true;
+ }
+
if (notifyClient && !buffer && !flags) {
- ALOGV("[%s] onWorkDone: Not reporting output buffer (%lld)",
- mName, work->input.ordinal.frameIndex.peekull());
- notifyClient = false;
+ if (mTunneled && drop && outputFormat) {
+ ALOGV("[%s] onWorkDone: Keep tunneled, drop frame with format change (%lld)",
+ mName, work->input.ordinal.frameIndex.peekull());
+ } else {
+ ALOGV("[%s] onWorkDone: Not reporting output buffer (%lld)",
+ mName, work->input.ordinal.frameIndex.peekull());
+ notifyClient = false;
+ }
}
if (buffer) {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index 4db69cb..26eef30 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -324,6 +324,8 @@
return mCrypto != nullptr || mDescrambler != nullptr;
}
std::atomic_bool mSendEncryptedInfoBuffer;
+
+ std::atomic_bool mTunneled;
};
// Conversion of a c2_status_t value to a status_t value may depend on the
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index 333a2ca..97e1a01 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -21,6 +21,7 @@
#include <C2PlatformSupport.h>
#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/MediaDefs.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/SkipCutBuffer.h>
@@ -132,6 +133,7 @@
if (!copy->copy(c2buffer)) {
return nullptr;
}
+ copy->meta()->extend(buffer->meta());
return copy;
}
@@ -199,6 +201,56 @@
mSkipCutBuffer = new SkipCutBuffer(skip, cut, mChannelCount);
}
+bool OutputBuffers::convert(
+ const std::shared_ptr<C2Buffer> &src, sp<Codec2Buffer> *dst) {
+ if (!src || src->data().type() != C2BufferData::LINEAR) {
+ return false;
+ }
+ int32_t configEncoding = kAudioEncodingPcm16bit;
+ int32_t codecEncoding = kAudioEncodingPcm16bit;
+ if (mFormat->findInt32("android._codec-pcm-encoding", &codecEncoding)
+ && mFormat->findInt32("android._config-pcm-encoding", &configEncoding)) {
+ if (mSrcEncoding != codecEncoding || mDstEncoding != configEncoding) {
+ if (codecEncoding != configEncoding) {
+ mDataConverter = AudioConverter::Create(
+ (AudioEncoding)codecEncoding, (AudioEncoding)configEncoding);
+ ALOGD_IF(mDataConverter, "[%s] Converter created from %d to %d",
+ mName, codecEncoding, configEncoding);
+ mFormatWithConverter = mFormat->dup();
+ mFormatWithConverter->setInt32(KEY_PCM_ENCODING, configEncoding);
+ } else {
+ mDataConverter = nullptr;
+ mFormatWithConverter = nullptr;
+ }
+ mSrcEncoding = codecEncoding;
+ mDstEncoding = configEncoding;
+ }
+ if (int encoding; !mFormat->findInt32(KEY_PCM_ENCODING, &encoding)
+ || encoding != mDstEncoding) {
+ }
+ }
+ if (!mDataConverter) {
+ return false;
+ }
+ sp<MediaCodecBuffer> srcBuffer = ConstLinearBlockBuffer::Allocate(mFormat, src);
+ if (!srcBuffer) {
+ return false;
+ }
+ if (!*dst) {
+ *dst = new Codec2Buffer(
+ mFormat,
+ new ABuffer(mDataConverter->targetSize(srcBuffer->size())));
+ }
+ sp<MediaCodecBuffer> dstBuffer = *dst;
+ status_t err = mDataConverter->convert(srcBuffer, dstBuffer);
+ if (err != OK) {
+ ALOGD("[%s] buffer conversion failed: %d", mName, err);
+ return false;
+ }
+ dstBuffer->setFormat(mFormatWithConverter);
+ return true;
+}
+
void OutputBuffers::clearStash() {
mPending.clear();
mReorderStash.clear();
@@ -1078,7 +1130,7 @@
return err;
}
c2Buffer->setFormat(mFormat);
- if (!c2Buffer->copy(buffer)) {
+ if (!convert(buffer, &c2Buffer) && !c2Buffer->copy(buffer)) {
ALOGD("[%s] copy buffer failed", mName);
return WOULD_BLOCK;
}
@@ -1194,9 +1246,12 @@
const std::shared_ptr<C2Buffer> &buffer,
size_t *index,
sp<MediaCodecBuffer> *clientBuffer) {
- sp<Codec2Buffer> newBuffer = wrap(buffer);
- if (newBuffer == nullptr) {
- return NO_MEMORY;
+ sp<Codec2Buffer> newBuffer;
+ if (!convert(buffer, &newBuffer)) {
+ newBuffer = wrap(buffer);
+ if (newBuffer == nullptr) {
+ return NO_MEMORY;
+ }
}
newBuffer->setFormat(mFormat);
*index = mImpl.assignSlot(newBuffer);
diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h
index 995d3a4..c8e9930 100644
--- a/media/codec2/sfplugin/CCodecBuffers.h
+++ b/media/codec2/sfplugin/CCodecBuffers.h
@@ -18,9 +18,11 @@
#define CCODEC_BUFFERS_H_
+#include <optional>
#include <string>
#include <C2Config.h>
+#include <DataConverter.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/MediaCodecBuffer.h>
@@ -382,6 +384,14 @@
*/
void submit(const sp<MediaCodecBuffer> &buffer);
+ /**
+ * Apply DataConverter from |src| to |*dst| if needed. If |*dst| is nullptr,
+ * a new buffer is allocated.
+ *
+ * Returns true if conversion was needed and executed; false otherwise.
+ */
+ bool convert(const std::shared_ptr<C2Buffer> &src, sp<Codec2Buffer> *dst);
+
private:
// SkipCutBuffer
int32_t mDelay;
@@ -391,6 +401,12 @@
void setSkipCutBuffer(int32_t skip, int32_t cut);
+ // DataConverter
+ sp<DataConverter> mDataConverter;
+ sp<AMessage> mFormatWithConverter;
+ std::optional<int32_t> mSrcEncoding;
+ std::optional<int32_t> mDstEncoding;
+
// Output stash
// Struct for an entry in the output stash (mPending and mReorderStash)
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index c275187..03418d9 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -657,24 +657,29 @@
add(ConfigMapper(KEY_SAMPLE_RATE, C2_PARAMKEY_CODED_SAMPLE_RATE, "value")
.limitTo(D::AUDIO & D::CODED));
- add(ConfigMapper(KEY_PCM_ENCODING, C2_PARAMKEY_PCM_ENCODING, "value")
+ auto pcmEncodingMapper = [](C2Value v) -> C2Value {
+ int32_t value;
+ C2Config::pcm_encoding_t to;
+ if (v.get(&value) && C2Mapper::map(value, &to)) {
+ return to;
+ }
+ return C2Value();
+ };
+ auto pcmEncodingReverse = [](C2Value v) -> C2Value {
+ C2Config::pcm_encoding_t value;
+ int32_t to;
+ using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(value)>::type;
+ if (v.get((C2ValueType*)&value) && C2Mapper::map(value, &to)) {
+ return to;
+ }
+ return C2Value();
+ };
+ add(ConfigMapper(KEY_PCM_ENCODING, C2_PARAMKEY_PCM_ENCODING, "value")
.limitTo(D::AUDIO)
- .withMappers([](C2Value v) -> C2Value {
- int32_t value;
- C2Config::pcm_encoding_t to;
- if (v.get(&value) && C2Mapper::map(value, &to)) {
- return to;
- }
- return C2Value();
- }, [](C2Value v) -> C2Value {
- C2Config::pcm_encoding_t value;
- int32_t to;
- using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(value)>::type;
- if (v.get((C2ValueType*)&value) && C2Mapper::map(value, &to)) {
- return to;
- }
- return C2Value();
- }));
+ .withMappers(pcmEncodingMapper, pcmEncodingReverse));
+ add(ConfigMapper("android._codec-pcm-encoding", C2_PARAMKEY_PCM_ENCODING, "value")
+ .limitTo(D::AUDIO & D::READ)
+ .withMappers(pcmEncodingMapper, pcmEncodingReverse));
add(ConfigMapper(KEY_IS_ADTS, C2_PARAMKEY_AAC_PACKAGING, "value")
.limitTo(D::AUDIO & D::CODED)
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
index 7c4bfb6..67d7ed2 100644
--- a/media/codec2/sfplugin/Codec2InfoBuilder.cpp
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -96,9 +96,12 @@
return false;
}
- // determine if codec supports HDR
+ // determine if codec supports HDR; imply 10-bit support
bool supportsHdr = false;
+ // determine if codec supports HDR10Plus; imply 10-bit support
bool supportsHdr10Plus = false;
+ // determine if codec supports 10-bit format
+ bool supports10Bit = false;
std::vector<std::shared_ptr<C2ParamDescriptor>> paramDescs;
c2_status_t err1 = intf->querySupportedParams(¶mDescs);
@@ -126,6 +129,10 @@
supportsHdr |= (mediaType == MIMETYPE_VIDEO_VP9);
supportsHdr |= (mediaType == MIMETYPE_VIDEO_AV1);
+ // HDR support implies 10-bit support.
+ // TODO: directly check this from the component interface
+ supports10Bit = (supportsHdr || supportsHdr10Plus);
+
bool added = false;
for (C2Value::Primitive profile : profileQuery[0].values.values) {
@@ -165,6 +172,12 @@
}
}
}
+ if (supports10Bit) {
+ auto bitnessMapper = C2Mapper::GetBitDepthProfileLevelMapper(trait.mediaType, 10);
+ if (bitnessMapper && bitnessMapper->mapProfile(pl.profile, &sdkProfile)) {
+ caps->addProfileLevel((uint32_t)sdkProfile, (uint32_t)sdkLevel);
+ }
+ }
} else if (!mapper) {
caps->addProfileLevel(pl.profile, pl.level);
}
diff --git a/media/codec2/sfplugin/FrameReassembler.cpp b/media/codec2/sfplugin/FrameReassembler.cpp
index af054c7..cb8b6ab 100644
--- a/media/codec2/sfplugin/FrameReassembler.cpp
+++ b/media/codec2/sfplugin/FrameReassembler.cpp
@@ -88,8 +88,7 @@
const sp<MediaCodecBuffer> &buffer,
std::list<std::unique_ptr<C2Work>> *items) {
int64_t timeUs;
- if (buffer->size() == 0u
- || !buffer->meta()->findInt64("timeUs", &timeUs)) {
+ if (!buffer->meta()->findInt64("timeUs", &timeUs)) {
return C2_BAD_VALUE;
}
diff --git a/media/codec2/sfplugin/tests/CCodecConfig_test.cpp b/media/codec2/sfplugin/tests/CCodecConfig_test.cpp
index 7c660dc..3615289 100644
--- a/media/codec2/sfplugin/tests/CCodecConfig_test.cpp
+++ b/media/codec2/sfplugin/tests/CCodecConfig_test.cpp
@@ -224,6 +224,17 @@
Copy<C2StreamBitrateInfo::output, C2StreamBitrateInfo::input>,
mInputBitrate)
.build());
+
+ addParameter(
+ DefineParam(mOutputProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
+ .withDefault(new C2StreamProfileLevelInfo::output(
+ 0u, PROFILE_UNUSED, LEVEL_UNUSED))
+ .withFields({
+ C2F(mOutputProfileLevel, profile).any(),
+ C2F(mOutputProfileLevel, level).any(),
+ })
+ .withSetter(Setter<C2StreamProfileLevelInfo::output>)
+ .build());
}
// TODO: more SDK params
@@ -241,6 +252,8 @@
std::shared_ptr<C2StreamPixelAspectRatioInfo::output> mPixelAspectRatio;
std::shared_ptr<C2StreamBitrateInfo::input> mInputBitrate;
std::shared_ptr<C2StreamBitrateInfo::output> mOutputBitrate;
+ std::shared_ptr<C2StreamProfileLevelInfo::input> mInputProfileLevel;
+ std::shared_ptr<C2StreamProfileLevelInfo::output> mOutputProfileLevel;
template<typename T>
static C2R Setter(bool, C2P<T> &) {
@@ -576,4 +589,51 @@
<< "mOutputFormat = " << mConfig.mOutputFormat->debugString().c_str();
}
+typedef std::tuple<std::string, C2Config::profile_t, int32_t> HdrProfilesParams;
+
+class HdrProfilesTest
+ : public CCodecConfigTest,
+ public ::testing::WithParamInterface<HdrProfilesParams> {
+};
+
+TEST_P(HdrProfilesTest, SetFromSdk) {
+ HdrProfilesParams params = GetParam();
+ std::string mediaType = std::get<0>(params);
+ C2Config::profile_t c2Profile = std::get<1>(params);
+ int32_t sdkProfile = std::get<2>(params);
+
+ init(C2Component::DOMAIN_VIDEO, C2Component::KIND_ENCODER, mediaType.c_str());
+
+ ASSERT_EQ(OK, mConfig.initialize(mReflector, mConfigurable));
+
+ sp<AMessage> format{new AMessage};
+ format->setInt32(KEY_PROFILE, sdkProfile);
+
+ std::vector<std::unique_ptr<C2Param>> configUpdate;
+ ASSERT_EQ(OK, mConfig.getConfigUpdateFromSdkParams(
+ mConfigurable, format, D::ALL, C2_MAY_BLOCK, &configUpdate));
+
+ ASSERT_EQ(1u, configUpdate.size());
+ C2StreamProfileLevelInfo::input *pl =
+ FindParam<std::remove_pointer<decltype(pl)>::type>(configUpdate);
+ ASSERT_NE(nullptr, pl);
+ ASSERT_EQ(c2Profile, pl->profile);
+}
+
+HdrProfilesParams kHdrProfilesParams[] = {
+ std::make_tuple(MIMETYPE_VIDEO_HEVC, PROFILE_HEVC_MAIN_10, HEVCProfileMain10HDR10),
+ std::make_tuple(MIMETYPE_VIDEO_HEVC, PROFILE_HEVC_MAIN_10, HEVCProfileMain10HDR10Plus),
+ std::make_tuple(MIMETYPE_VIDEO_VP9, PROFILE_VP9_2, VP9Profile2HDR),
+ std::make_tuple(MIMETYPE_VIDEO_VP9, PROFILE_VP9_2, VP9Profile2HDR10Plus),
+ std::make_tuple(MIMETYPE_VIDEO_VP9, PROFILE_VP9_3, VP9Profile3HDR),
+ std::make_tuple(MIMETYPE_VIDEO_VP9, PROFILE_VP9_3, VP9Profile3HDR10Plus),
+ std::make_tuple(MIMETYPE_VIDEO_AV1, PROFILE_AV1_0, AV1ProfileMain10HDR10),
+ std::make_tuple(MIMETYPE_VIDEO_AV1, PROFILE_AV1_0, AV1ProfileMain10HDR10Plus),
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ CCodecConfig,
+ HdrProfilesTest,
+ ::testing::ValuesIn(kHdrProfilesParams));
+
} // namespace android
diff --git a/media/codec2/sfplugin/tests/FrameReassembler_test.cpp b/media/codec2/sfplugin/tests/FrameReassembler_test.cpp
index 6738ee7..0be934a 100644
--- a/media/codec2/sfplugin/tests/FrameReassembler_test.cpp
+++ b/media/codec2/sfplugin/tests/FrameReassembler_test.cpp
@@ -53,7 +53,8 @@
C2Config::pcm_encoding_t encoding,
size_t inputFrameSizeInBytes,
size_t count,
- size_t expectedOutputSize) {
+ size_t expectedOutputSize,
+ bool separateEos) {
FrameReassembler frameReassembler;
frameReassembler.init(
mPool,
@@ -67,7 +68,7 @@
size_t inputIndex = 0, outputIndex = 0;
size_t expectCount = 0;
- for (size_t i = 0; i < count; ++i) {
+ for (size_t i = 0; i < count + (separateEos ? 1 : 0); ++i) {
sp<MediaCodecBuffer> buffer = new MediaCodecBuffer(
new AMessage, new ABuffer(inputFrameSizeInBytes));
buffer->setRange(0, inputFrameSizeInBytes);
@@ -77,8 +78,12 @@
if (i == count - 1) {
buffer->meta()->setInt32("eos", 1);
}
- for (size_t j = 0; j < inputFrameSizeInBytes; ++j, ++inputIndex) {
- buffer->base()[j] = (inputIndex & 0xFF);
+ if (i == count && separateEos) {
+ buffer->setRange(0, 0);
+ } else {
+ for (size_t j = 0; j < inputFrameSizeInBytes; ++j, ++inputIndex) {
+ buffer->base()[j] = (inputIndex & 0xFF);
+ }
}
std::list<std::unique_ptr<C2Work>> items;
ASSERT_EQ(C2_OK, frameReassembler.process(buffer, &items));
@@ -105,7 +110,8 @@
ASSERT_EQ(encoderFrameSize * BytesPerSample(encoding), view.capacity());
for (size_t j = 0; j < view.capacity(); ++j, ++outputIndex) {
ASSERT_TRUE(outputIndex < inputIndex
- || inputIndex == inputFrameSizeInBytes * count);
+ || inputIndex == inputFrameSizeInBytes * count)
+ << "inputIndex = " << inputIndex << " outputIndex = " << outputIndex;
uint8_t expected = outputIndex < inputIndex ? (outputIndex & 0xFF) : 0;
if (expectCount < 10) {
++expectCount;
@@ -137,204 +143,239 @@
// Push frames with exactly the same size as the encoder requested.
TEST_F(FrameReassemblerTest, PushExactFrameSize) {
ASSERT_EQ(OK, initStatus());
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_8,
- 1024 /* input frame size in bytes = 1024 samples * 1 channel * 1 bytes/sample */,
- 10 /* count */,
- 10240 /* expected output size = 10 * 1024 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_16,
- 2048 /* input frame size in bytes = 1024 samples * 1 channel * 2 bytes/sample */,
- 10 /* count */,
- 20480 /* expected output size = 10 * 2048 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_FLOAT,
- 4096 /* input frame size in bytes = 1024 samples * 1 channel * 4 bytes/sample */,
- 10 /* count */,
- 40960 /* expected output size = 10 * 4096 bytes/frame */);
+ for (bool separateEos : {false, true}) {
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_8,
+ 1024 /* input frame size in bytes = 1024 samples * 1 channel * 1 bytes/sample */,
+ 10 /* count */,
+ 10240 /* expected output size = 10 * 1024 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_16,
+ 2048 /* input frame size in bytes = 1024 samples * 1 channel * 2 bytes/sample */,
+ 10 /* count */,
+ 20480 /* expected output size = 10 * 2048 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_FLOAT,
+ 4096 /* input frame size in bytes = 1024 samples * 1 channel * 4 bytes/sample */,
+ 10 /* count */,
+ 40960 /* expected output size = 10 * 4096 bytes/frame */,
+ separateEos);
+ }
}
// Push frames with half the size that the encoder requested.
TEST_F(FrameReassemblerTest, PushHalfFrameSize) {
ASSERT_EQ(OK, initStatus());
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_8,
- 512 /* input frame size in bytes = 512 samples * 1 channel * 1 bytes per sample */,
- 10 /* count */,
- 5120 /* expected output size = 5 * 1024 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_16,
- 1024 /* input frame size in bytes = 512 samples * 1 channel * 2 bytes per sample */,
- 10 /* count */,
- 10240 /* expected output size = 5 * 2048 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_FLOAT,
- 2048 /* input frame size in bytes = 512 samples * 1 channel * 4 bytes per sample */,
- 10 /* count */,
- 20480 /* expected output size = 5 * 4096 bytes/frame */);
+ for (bool separateEos : {false, true}) {
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_8,
+ 512 /* input frame size in bytes = 512 samples * 1 channel * 1 bytes/sample */,
+ 10 /* count */,
+ 5120 /* expected output size = 5 * 1024 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_16,
+ 1024 /* input frame size in bytes = 512 samples * 1 channel * 2 bytes/sample */,
+ 10 /* count */,
+ 10240 /* expected output size = 5 * 2048 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_FLOAT,
+ 2048 /* input frame size in bytes = 512 samples * 1 channel * 4 bytes/sample */,
+ 10 /* count */,
+ 20480 /* expected output size = 5 * 4096 bytes/frame */,
+ separateEos);
+ }
}
// Push frames with twice the size that the encoder requested.
TEST_F(FrameReassemblerTest, PushDoubleFrameSize) {
ASSERT_EQ(OK, initStatus());
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_8,
- 2048 /* input frame size in bytes = 2048 samples * 1 channel * 1 bytes per sample */,
- 10 /* count */,
- 20480 /* expected output size = 20 * 1024 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_16,
- 4096 /* input frame size in bytes = 2048 samples * 1 channel * 2 bytes per sample */,
- 10 /* count */,
- 40960 /* expected output size = 20 * 2048 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_FLOAT,
- 8192 /* input frame size in bytes = 2048 samples * 1 channel * 4 bytes per sample */,
- 10 /* count */,
- 81920 /* expected output size = 20 * 4096 bytes/frame */);
+ for (bool separateEos : {false, true}) {
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_8,
+ 2048 /* input frame size in bytes = 2048 samples * 1 channel * 1 bytes/sample */,
+ 10 /* count */,
+ 20480 /* expected output size = 20 * 1024 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_16,
+ 4096 /* input frame size in bytes = 2048 samples * 1 channel * 2 bytes/sample */,
+ 10 /* count */,
+ 40960 /* expected output size = 20 * 2048 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_FLOAT,
+ 8192 /* input frame size in bytes = 2048 samples * 1 channel * 4 bytes/sample */,
+ 10 /* count */,
+ 81920 /* expected output size = 20 * 4096 bytes/frame */,
+ separateEos);
+ }
}
// Push frames with a little bit larger (+5 samples) than the requested size.
TEST_F(FrameReassemblerTest, PushLittleLargerFrameSize) {
ASSERT_EQ(OK, initStatus());
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_8,
- 1029 /* input frame size in bytes = 1029 samples * 1 channel * 1 bytes per sample */,
- 10 /* count */,
- 11264 /* expected output size = 11 * 1024 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_16,
- 2058 /* input frame size in bytes = 1029 samples * 1 channel * 2 bytes per sample */,
- 10 /* count */,
- 22528 /* expected output size = 11 * 2048 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_FLOAT,
- 4116 /* input frame size in bytes = 1029 samples * 1 channel * 4 bytes per sample */,
- 10 /* count */,
- 45056 /* expected output size = 11 * 4096 bytes/frame */);
+ for (bool separateEos : {false, true}) {
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_8,
+ 1029 /* input frame size in bytes = 1029 samples * 1 channel * 1 bytes/sample */,
+ 10 /* count */,
+ 11264 /* expected output size = 11 * 1024 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_16,
+ 2058 /* input frame size in bytes = 1029 samples * 1 channel * 2 bytes/sample */,
+ 10 /* count */,
+ 22528 /* expected output size = 11 * 2048 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_FLOAT,
+ 4116 /* input frame size in bytes = 1029 samples * 1 channel * 4 bytes/sample */,
+ 10 /* count */,
+ 45056 /* expected output size = 11 * 4096 bytes/frame */,
+ separateEos);
+ }
}
// Push frames with a little bit smaller (-5 samples) than the requested size.
TEST_F(FrameReassemblerTest, PushLittleSmallerFrameSize) {
ASSERT_EQ(OK, initStatus());
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_8,
- 1019 /* input frame size in bytes = 1019 samples * 1 channel * 1 bytes per sample */,
- 10 /* count */,
- 10240 /* expected output size = 10 * 1024 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_16,
- 2038 /* input frame size in bytes = 1019 samples * 1 channel * 2 bytes per sample */,
- 10 /* count */,
- 20480 /* expected output size = 10 * 2048 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_FLOAT,
- 4076 /* input frame size in bytes = 1019 samples * 1 channel * 4 bytes per sample */,
- 10 /* count */,
- 40960 /* expected output size = 10 * 4096 bytes/frame */);
+ for (bool separateEos : {false, true}) {
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_8,
+ 1019 /* input frame size in bytes = 1019 samples * 1 channel * 1 bytes/sample */,
+ 10 /* count */,
+ 10240 /* expected output size = 10 * 1024 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_16,
+ 2038 /* input frame size in bytes = 1019 samples * 1 channel * 2 bytes/sample */,
+ 10 /* count */,
+ 20480 /* expected output size = 10 * 2048 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_FLOAT,
+ 4076 /* input frame size in bytes = 1019 samples * 1 channel * 4 bytes/sample */,
+ 10 /* count */,
+ 40960 /* expected output size = 10 * 4096 bytes/frame */,
+ separateEos);
+ }
}
// Push single-byte frames
TEST_F(FrameReassemblerTest, PushSingleByte) {
ASSERT_EQ(OK, initStatus());
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_8,
- 1 /* input frame size in bytes */,
- 100000 /* count */,
- 100352 /* expected output size = 98 * 1024 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_16,
- 1 /* input frame size in bytes */,
- 100000 /* count */,
- 100352 /* expected output size = 49 * 2048 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_FLOAT,
- 1 /* input frame size in bytes */,
- 100000 /* count */,
- 102400 /* expected output size = 25 * 4096 bytes/frame */);
+ for (bool separateEos : {false, true}) {
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_8,
+ 1 /* input frame size in bytes */,
+ 100000 /* count */,
+ 100352 /* expected output size = 98 * 1024 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_16,
+ 1 /* input frame size in bytes */,
+ 100000 /* count */,
+ 100352 /* expected output size = 49 * 2048 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_FLOAT,
+ 1 /* input frame size in bytes */,
+ 100000 /* count */,
+ 102400 /* expected output size = 25 * 4096 bytes/frame */,
+ separateEos);
+ }
}
// Push one big chunk.
TEST_F(FrameReassemblerTest, PushBigChunk) {
ASSERT_EQ(OK, initStatus());
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_8,
- 100000 /* input frame size in bytes */,
- 1 /* count */,
- 100352 /* expected output size = 98 * 1024 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_16,
- 100000 /* input frame size in bytes */,
- 1 /* count */,
- 100352 /* expected output size = 49 * 2048 bytes/frame */);
- testPushSameSize(
- 1024 /* frame size in samples */,
- 48000 /* sample rate */,
- 1 /* channel count */,
- PCM_FLOAT,
- 100000 /* input frame size in bytes */,
- 1 /* count */,
- 102400 /* expected output size = 25 * 4096 bytes/frame */);
+ for (bool separateEos : {false, true}) {
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_8,
+ 100000 /* input frame size in bytes */,
+ 1 /* count */,
+ 100352 /* expected output size = 98 * 1024 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_16,
+ 100000 /* input frame size in bytes */,
+ 1 /* count */,
+ 100352 /* expected output size = 49 * 2048 bytes/frame */,
+ separateEos);
+ testPushSameSize(
+ 1024 /* frame size in samples */,
+ 48000 /* sample rate */,
+ 1 /* channel count */,
+ PCM_FLOAT,
+ 100000 /* input frame size in bytes */,
+ 1 /* count */,
+ 102400 /* expected output size = 25 * 4096 bytes/frame */,
+ separateEos);
+ }
}
} // namespace android
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
index 5f87c66..2213001 100644
--- a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
@@ -118,6 +118,22 @@
} // namespace
+bool IsFormatR10G10B10A2SupportedForLegacyRendering() {
+ const AHardwareBuffer_Desc desc = {
+ .width = 320,
+ .height = 240,
+ .format = AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM,
+ .layers = 1,
+ .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
+ AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
+ .stride = 0,
+ .rfu0 = 0,
+ .rfu1 = 0,
+ };
+
+ return AHardwareBuffer_isSupported(&desc);
+}
+
status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view) {
if (view.crop().width != img->mWidth || view.crop().height != img->mHeight) {
return BAD_VALUE;
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.h b/media/codec2/sfplugin/utils/Codec2BufferUtils.h
index 9fa642d..c4651a4 100644
--- a/media/codec2/sfplugin/utils/Codec2BufferUtils.h
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.h
@@ -27,6 +27,11 @@
namespace android {
/**
+ * Check if R10G10B10A2 is supported in legacy rendering path that involves GPU
+ */
+bool IsFormatR10G10B10A2SupportedForLegacyRendering();
+
+/**
* Converts an RGB view to planar YUV 420 media image.
*
* \param dstY pointer to media image buffer
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.cpp b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
index 4d939fa..f557830 100644
--- a/media/codec2/sfplugin/utils/Codec2Mapper.cpp
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
@@ -255,6 +255,8 @@
{ C2Config::PROFILE_HEVC_MAIN_STILL, HEVCProfileMainStill },
{ C2Config::PROFILE_HEVC_MAIN_INTRA, HEVCProfileMain },
{ C2Config::PROFILE_HEVC_MAIN_10_INTRA, HEVCProfileMain10 },
+ { C2Config::PROFILE_HEVC_MAIN_10, HEVCProfileMain10HDR10 },
+ { C2Config::PROFILE_HEVC_MAIN_10, HEVCProfileMain10HDR10Plus },
};
ALookup<C2Config::profile_t, int32_t> sHevcHdrProfiles = {
@@ -381,15 +383,17 @@
{ C2Config::LEVEL_AV1_7_3, AV1Level73 },
};
-
ALookup<C2Config::profile_t, int32_t> sAv1Profiles = {
- // TODO: will need to disambiguate between Main8 and Main10
{ C2Config::PROFILE_AV1_0, AV1ProfileMain8 },
{ C2Config::PROFILE_AV1_0, AV1ProfileMain10 },
{ C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10 },
{ C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10Plus },
};
+ALookup<C2Config::profile_t, int32_t> sAv1TenbitProfiles = {
+ { C2Config::PROFILE_AV1_0, AV1ProfileMain10 },
+};
+
ALookup<C2Config::profile_t, int32_t> sAv1HdrProfiles = {
{ C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10 },
};
@@ -603,9 +607,9 @@
};
struct Av1ProfileLevelMapper : ProfileLevelMapperHelper {
- Av1ProfileLevelMapper(bool isHdr = false, bool isHdr10Plus = false) :
+ Av1ProfileLevelMapper(bool isHdr = false, bool isHdr10Plus = false, int32_t bitDepth = 8) :
ProfileLevelMapperHelper(),
- mIsHdr(isHdr), mIsHdr10Plus(isHdr10Plus) {}
+ mIsHdr(isHdr), mIsHdr10Plus(isHdr10Plus), mBitDepth(bitDepth) {}
virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
return sAv1Levels.map(from, to);
@@ -614,19 +618,22 @@
return sAv1Levels.map(from, to);
}
virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
- return mIsHdr10Plus ? sAv1Hdr10PlusProfiles.map(from, to) :
- mIsHdr ? sAv1HdrProfiles.map(from, to) :
- sAv1Profiles.map(from, to);
+ return (mBitDepth == 10) ? sAv1TenbitProfiles.map(from, to) :
+ mIsHdr10Plus ? sAv1Hdr10PlusProfiles.map(from, to) :
+ mIsHdr ? sAv1HdrProfiles.map(from, to) :
+ sAv1Profiles.map(from, to);
}
virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
- return mIsHdr10Plus ? sAv1Hdr10PlusProfiles.map(from, to) :
- mIsHdr ? sAv1HdrProfiles.map(from, to) :
- sAv1Profiles.map(from, to);
+ return (mBitDepth == 10) ? sAv1TenbitProfiles.map(from, to) :
+ mIsHdr10Plus ? sAv1Hdr10PlusProfiles.map(from, to) :
+ mIsHdr ? sAv1HdrProfiles.map(from, to) :
+ sAv1Profiles.map(from, to);
}
private:
bool mIsHdr;
bool mIsHdr10Plus;
+ int32_t mBitDepth;
};
} // namespace
@@ -674,6 +681,18 @@
}
// static
+std::shared_ptr<C2Mapper::ProfileLevelMapper>
+C2Mapper::GetBitDepthProfileLevelMapper(std::string mediaType, int32_t bitDepth) {
+ std::transform(mediaType.begin(), mediaType.end(), mediaType.begin(), ::tolower);
+ if (bitDepth == 8) {
+ return GetProfileLevelMapper(mediaType);
+ } else if (mediaType == MIMETYPE_VIDEO_AV1 && bitDepth == 10) {
+ return std::make_shared<Av1ProfileLevelMapper>(false, false, bitDepth);
+ }
+ return nullptr;
+}
+
+// static
bool C2Mapper::map(C2Config::bitrate_mode_t from, int32_t *to) {
return sBitrateModes.map(from, to);
}
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.h b/media/codec2/sfplugin/utils/Codec2Mapper.h
index 797c8a8..33d305e 100644
--- a/media/codec2/sfplugin/utils/Codec2Mapper.h
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.h
@@ -43,6 +43,9 @@
static std::shared_ptr<ProfileLevelMapper>
GetHdrProfileLevelMapper(std::string mediaType, bool isHdr10Plus = false);
+ static std::shared_ptr<ProfileLevelMapper>
+ GetBitDepthProfileLevelMapper(std::string mediaType, int32_t bitDepth = 8);
+
// convert between bitrates
static bool map(C2Config::bitrate_mode_t, int32_t*);
static bool map(int32_t, C2Config::bitrate_mode_t*);
diff --git a/media/codec2/vndk/platform/C2BqBuffer.cpp b/media/codec2/vndk/platform/C2BqBuffer.cpp
index 169de0c..01995fd 100644
--- a/media/codec2/vndk/platform/C2BqBuffer.cpp
+++ b/media/codec2/vndk/platform/C2BqBuffer.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "C2BqBuffer"
+#include <android/hardware_buffer.h>
#include <utils/Log.h>
#include <ui/BufferQueueDefs.h>
@@ -171,6 +172,91 @@
return stamp;
}
+// Do not rely on AHardwareBuffer module for GraphicBuffer handling since AHardwareBuffer
+// module is linked to framework which could have a different implementation of GraphicBuffer
+// than mainline/vndk implementation.(See b/203347494.)
+//
+// b2h/h2b between HardwareBuffer and GraphicBuffer cannot be used. (b2h/h2b depend on
+// AHardwareBuffer module for the conversion between HardwareBuffer and GraphicBuffer.)
+// hgbp_ prefixed methods are added to be used instead of b2h/h2b.
+//
+// TODO: Remove dependency with existing AHwB module. Also clean up conversions.(conversions here
+// and h2b/b2h coversions)
+const GraphicBuffer* hgbp_AHBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer) {
+ return GraphicBuffer::fromAHardwareBuffer(buffer);
+}
+
+int hgbp_createFromHandle(const AHardwareBuffer_Desc* desc,
+ const native_handle_t* handle,
+ sp<GraphicBuffer> *outBuffer) {
+
+ if (!desc || !handle || !outBuffer) return ::android::BAD_VALUE;
+ if (desc->rfu0 != 0 || desc->rfu1 != 0) return ::android::BAD_VALUE;
+ if (desc->format == AHARDWAREBUFFER_FORMAT_BLOB && desc->height != 1)
+ return ::android::BAD_VALUE;
+
+ const int format = uint32_t(desc->format);
+ const uint64_t usage = uint64_t(desc->usage);
+ sp<GraphicBuffer> gbuffer(new GraphicBuffer(handle,
+ GraphicBuffer::HandleWrapMethod::CLONE_HANDLE,
+ desc->width, desc->height,
+ format, desc->layers, usage, desc->stride));
+ status_t err = gbuffer->initCheck();
+ if (err != 0 || gbuffer->handle == 0) return err;
+
+ *outBuffer = gbuffer;
+
+ return ::android::NO_ERROR;
+}
+
+void hgbp_describe(const AHardwareBuffer* buffer,
+ AHardwareBuffer_Desc* outDesc) {
+ if (!buffer || !outDesc) return;
+
+ const GraphicBuffer* gbuffer = hgbp_AHBuffer_to_GraphicBuffer(buffer);
+
+ outDesc->width = gbuffer->getWidth();
+ outDesc->height = gbuffer->getHeight();
+ outDesc->layers = gbuffer->getLayerCount();
+ outDesc->format = uint32_t(gbuffer->getPixelFormat());
+ outDesc->usage = uint64_t(gbuffer->getUsage());
+ outDesc->stride = gbuffer->getStride();
+ outDesc->rfu0 = 0;
+ outDesc->rfu1 = 0;
+}
+
+
+bool hgbp_h2b(HBuffer const& from, sp<GraphicBuffer>* to) {
+ AHardwareBuffer_Desc const* desc =
+ reinterpret_cast<AHardwareBuffer_Desc const*>(
+ from.description.data());
+ native_handle_t const* handle = from.nativeHandle;
+ if (hgbp_createFromHandle(desc, handle, to) != ::android::OK) {
+ return false;
+ }
+ return true;
+}
+
+bool hgbp_b2h(sp<GraphicBuffer> const& from, HBuffer* to,
+ uint32_t* toGenerationNumber) {
+ if (!from) {
+ return false;
+ }
+ AHardwareBuffer* hwBuffer = from->toAHardwareBuffer();
+ to->nativeHandle.setTo(
+ const_cast<native_handle_t*>(from->handle),
+ false);
+ hgbp_describe(
+ hwBuffer,
+ reinterpret_cast<AHardwareBuffer_Desc*>(to->description.data()));
+ if (toGenerationNumber) {
+ *toGenerationNumber = from->getGenerationNumber();
+ }
+ return true;
+}
+
+// End of hgbp methods for GraphicBuffer creation.
+
bool getGenerationNumberAndUsage(const sp<HGraphicBufferProducer> &producer,
uint32_t *generation, uint64_t *usage) {
status_t status{};
@@ -211,7 +297,7 @@
HBuffer const& hBuffer,
uint32_t generationNumber){
if (h2b(hStatus, &status) &&
- h2b(hBuffer, &slotBuffer) &&
+ hgbp_h2b(hBuffer, &slotBuffer) &&
slotBuffer) {
*generation = generationNumber;
*usage = slotBuffer->getUsage();
@@ -402,7 +488,7 @@
HBuffer const& hBuffer,
uint32_t generationNumber){
if (h2b(hStatus, &status) &&
- h2b(hBuffer, &slotBuffer) &&
+ hgbp_h2b(hBuffer, &slotBuffer) &&
slotBuffer) {
slotBuffer->setGenerationNumber(generationNumber);
outGeneration = generationNumber;
@@ -804,7 +890,7 @@
HBuffer hBuffer{};
uint32_t hGenerationNumber{};
- if (!b2h(graphicBuffer, &hBuffer, &hGenerationNumber)) {
+ if (!hgbp_b2h(graphicBuffer, &hBuffer, &hGenerationNumber)) {
ALOGD("I to O conversion failed");
return -1;
}
diff --git a/media/codecs/m4v_h263/enc/src/fastidct.cpp b/media/codecs/m4v_h263/enc/src/fastidct.cpp
index 688effc..ec1b28f 100644
--- a/media/codecs/m4v_h263/enc/src/fastidct.cpp
+++ b/media/codecs/m4v_h263/enc/src/fastidct.cpp
@@ -76,6 +76,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_col2(Short *blk)
{
int32 x0, x1, x3, x5, x7;//, x8;
@@ -102,6 +104,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_col3(Short *blk)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -137,6 +141,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_col4(Short *blk)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -180,6 +186,8 @@
}
#ifndef SMALL_DCT
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_col0x40(Short *blk)
{
int32 x1, x3, x5, x7;//, x8;
@@ -230,6 +238,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_col0x10(Short *blk)
{
int32 x1, x3, x5, x7;
@@ -256,6 +266,8 @@
#endif /* SMALL_DCT */
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_col(Short *blk)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -368,6 +380,8 @@
return;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row2Inter(Short *blk, UChar *rec, Int lx)
{
int32 x0, x1, x2, x4, x5;
@@ -427,6 +441,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row3Inter(Short *blk, UChar *rec, Int lx)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -497,6 +513,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row4Inter(Short *blk, UChar *rec, Int lx)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -573,6 +591,8 @@
}
#ifndef SMALL_DCT
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row0x40Inter(Short *blk, UChar *rec, Int lx)
{
int32 x1, x2, x4, x5;
@@ -686,6 +706,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row0x10Inter(Short *blk, UChar *rec, Int lx)
{
int32 x1, x3, x5, x7;
@@ -741,6 +763,8 @@
#endif /* SMALL_DCT */
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_rowInter(Short *blk, UChar *rec, Int lx)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -864,6 +888,8 @@
return;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row2Intra(Short *blk, UChar *rec, Int lx)
{
int32 x0, x1, x2, x4, x5;
@@ -919,6 +945,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row3Intra(Short *blk, UChar *rec, Int lx)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -985,6 +1013,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row4Intra(Short *blk, UChar *rec, Int lx)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -1058,6 +1088,8 @@
}
#ifndef SMALL_DCT
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row0x40Intra(Short *blk, UChar *rec, Int lx)
{
int32 x1, x2, x4, x5;
@@ -1166,6 +1198,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row0x10Intra(Short *blk, UChar *rec, Int lx)
{
int32 x1, x3, x5, x7;
@@ -1218,6 +1252,8 @@
}
#endif /* SMALL_DCT */
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_rowIntra(Short *blk, UChar *rec, Int lx)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -1364,6 +1400,8 @@
return;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row2zmv(Short *blk, UChar *rec, UChar *pred, Int lx)
{
int32 x0, x1, x2, x4, x5;
@@ -1424,6 +1462,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row3zmv(Short *blk, UChar *rec, UChar *pred, Int lx)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -1495,6 +1535,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row4zmv(Short *blk, UChar *rec, UChar *pred, Int lx)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
@@ -1572,6 +1614,8 @@
}
#ifndef SMALL_DCT
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row0x40zmv(Short *blk, UChar *rec, UChar *pred, Int lx)
{
int32 x1, x2, x4, x5;
@@ -1687,6 +1731,8 @@
return ;
}
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_row0x10zmv(Short *blk, UChar *rec, UChar *pred, Int lx)
{
int32 x1, x3, x5, x7;
@@ -1743,6 +1789,8 @@
#endif /* SMALL_DCT */
+/* Ignoring overflows as idct function expects and uses overflows */
+__attribute__((no_sanitize("signed-integer-overflow")))
void idct_rowzmv(Short *blk, UChar *rec, UChar *pred, Int lx)
{
int32 x0, x1, x2, x3, x4, x5, x6, x7, x8;
diff --git a/media/codecs/m4v_h263/enc/src/mp4enc_api.cpp b/media/codecs/m4v_h263/enc/src/mp4enc_api.cpp
index 00b2ab6..b295258 100644
--- a/media/codecs/m4v_h263/enc/src/mp4enc_api.cpp
+++ b/media/codecs/m4v_h263/enc/src/mp4enc_api.cpp
@@ -501,13 +501,16 @@
/* check frame rate */
for (i = 0; i < encParams->nLayers; i++)
{
+ if (encOption->encFrameRate[i] <= 0. || encOption->encFrameRate[i] > 120)
+ {
+ goto CLEAN_UP;
+ }
encParams->LayerFrameRate[i] = encOption->encFrameRate[i];
}
if (encParams->nLayers > 1)
{
- if (encOption->encFrameRate[0] == encOption->encFrameRate[1] ||
- encOption->encFrameRate[0] == 0. || encOption->encFrameRate[1] == 0.) /* 7/31/03 */
+ if (encOption->encFrameRate[0] == encOption->encFrameRate[1])
goto CLEAN_UP;
}
/* set max frame rate */
diff --git a/media/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp b/media/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
index 912c821..5e613d9 100644
--- a/media/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
+++ b/media/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
@@ -50,7 +50,7 @@
private:
tagvideoDecControls *mDecHandle = nullptr;
- uint8_t *mOutputBuffer[kNumOutputBuffers];
+ uint8_t *mOutputBuffer[kNumOutputBuffers] = {};
bool mInitialized = false;
bool mFramesConfigured = false;
#ifdef MPEG4
diff --git a/media/codecs/mp3dec/src/pvmp3_stereo_proc.cpp b/media/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
index 4338c43..c04f7f3 100644
--- a/media/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
+++ b/media/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
@@ -219,6 +219,9 @@
; FUNCTION CODE
----------------------------------------------------------------------------*/
+#if __has_attribute(no_sanitize)
+__attribute__((no_sanitize("integer")))
+#endif
void pvmp3_st_intensity(int32 xr[SUBBANDS_NUMBER*FILTERBANK_BANDS],
int32 xl[SUBBANDS_NUMBER*FILTERBANK_BANDS],
int32 is_pos,
diff --git a/media/extractors/tests/Android.bp b/media/extractors/tests/Android.bp
index 5d97d9a..23c74f7 100644
--- a/media/extractors/tests/Android.bp
+++ b/media/extractors/tests/Android.bp
@@ -45,14 +45,11 @@
"libdatasource",
"libwatchdog",
- "libstagefright",
"libstagefright_id3",
"libstagefright_flacdec",
"libstagefright_esds",
"libstagefright_mpeg2support",
- "libstagefright_mpeg2extractor",
"libstagefright_foundation_colorutils_ndk",
- "libstagefright_foundation",
"libstagefright_metadatautils",
"libmedia_midiiowrapper",
@@ -74,6 +71,8 @@
"libcutils",
"libmediandk",
"libmedia",
+ "libstagefright",
+ "libstagefright_foundation",
"libcrypto",
"libhidlmemory",
"libhidlbase",
diff --git a/media/janitors/codec_OWNERS b/media/janitors/codec_OWNERS
index e201399..d4ee51b 100644
--- a/media/janitors/codec_OWNERS
+++ b/media/janitors/codec_OWNERS
@@ -2,4 +2,4 @@
# differentiated from plugins connecting those codecs to either omx or codec2 infrastructure
essick@google.com
lajos@google.com
-marcone@google.com
+wonsik@google.com
diff --git a/media/janitors/reliability_mainline_OWNERS b/media/janitors/reliability_mainline_OWNERS
new file mode 100644
index 0000000..e4c4fc2
--- /dev/null
+++ b/media/janitors/reliability_mainline_OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 1051309
+# go/android-media-relaibility
+
+essick@google.com
+nchalko@google.com
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 9c307ff..b0f155a 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -133,6 +133,7 @@
"libutils",
"libvibrator",
"framework-permission-aidl-cpp",
+ "packagemanager_aidl-cpp",
],
export_shared_lib_headers: [
"audioflinger-aidl-cpp",
@@ -197,7 +198,7 @@
],
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth.updatable",
+ "com.android.bluetooth",
"com.android.media",
"com.android.media.swcodec",
],
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index a1d3bdb..4ff05e4 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -205,16 +205,18 @@
// Otherwise the callback thread will never exit.
stop();
if (mAudioRecordThread != 0) {
- mProxy->interrupt();
mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
+ mProxy->interrupt();
mAudioRecordThread->requestExitAndWait();
mAudioRecordThread.clear();
}
- // No lock here: worst case we remove a NULL callback which will be a nop
+
+ AutoMutex lock(mLock);
if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) {
// This may not stop all of these device callbacks!
// TODO: Add some sort of protection.
AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
+ mDeviceCallback.clear();
}
}
status_t AudioRecord::set(
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index f1eeaa3..4bfafe4 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1960,8 +1960,8 @@
return result.value_or(false);
}
-status_t AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
- std::vector<audio_format_t>* formats) {
+status_t AudioSystem::getHwOffloadFormatsSupportedForBluetoothMedia(
+ audio_devices_t device, std::vector<audio_format_t>* formats) {
if (formats == nullptr) {
return BAD_VALUE;
}
@@ -1971,8 +1971,10 @@
if (aps == 0) return PERMISSION_DENIED;
std::vector<media::audio::common::AudioFormat> formatsAidl;
+ int32_t deviceAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_devices_t_int32_t(device));
+
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
- aps->getHwOffloadEncodingFormatsSupportedForA2DP(&formatsAidl)));
+ aps->getHwOffloadFormatsSupportedForBluetoothMedia(deviceAidl, &formatsAidl)));
*formats = VALUE_OR_RETURN_STATUS(
convertContainer<std::vector<audio_format_t>>(formatsAidl,
aidl2legacy_AudioFormat_audio_format_t));
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 3bc666b..f0a105a 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -353,12 +353,13 @@
// Otherwise the callback thread will never exit.
stop();
if (mAudioTrackThread != 0) { // not thread safe
- mProxy->interrupt();
mAudioTrackThread->requestExit(); // see comment in AudioTrack.h
+ mProxy->interrupt();
mAudioTrackThread->requestExitAndWait();
mAudioTrackThread.clear();
}
- // No lock here: worst case we remove a NULL callback which will be a nop
+
+ AutoMutex lock(mLock);
if (mDeviceCallback != 0 && mOutput != AUDIO_IO_HANDLE_NONE) {
// This may not stop all of these device callbacks!
// TODO: Add some sort of protection.
diff --git a/media/libaudioclient/AudioTrackShared.cpp b/media/libaudioclient/AudioTrackShared.cpp
index 35719be..e3b79b2 100644
--- a/media/libaudioclient/AudioTrackShared.cpp
+++ b/media/libaudioclient/AudioTrackShared.cpp
@@ -409,7 +409,7 @@
android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
// it seems that a FUTEX_WAKE_PRIVATE will not wake a FUTEX_WAIT, even within same process
(void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
- 1);
+ INT_MAX);
}
}
@@ -419,7 +419,7 @@
if (!(android_atomic_or(CBLK_INTERRUPT, &cblk->mFlags) & CBLK_INTERRUPT)) {
android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
(void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
- 1);
+ INT_MAX);
}
}
@@ -490,6 +490,8 @@
status_t AudioTrackClientProxy::waitStreamEndDone(const struct timespec *requested)
{
struct timespec total; // total elapsed time spent waiting
+ struct timespec before;
+ bool beforeIsValid = false;
total.tv_sec = 0;
total.tv_nsec = 0;
audio_track_cblk_t* cblk = mCblk;
@@ -570,17 +572,38 @@
}
int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
if (!(old & CBLK_FUTEX_WAKE)) {
+ if (!beforeIsValid) {
+ clock_gettime(CLOCK_MONOTONIC, &before);
+ beforeIsValid = true;
+ }
errno = 0;
(void) syscall(__NR_futex, &cblk->mFutex,
mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
- switch (errno) {
+ status_t error = errno; // clock_gettime can affect errno
+ {
+ struct timespec after;
+ clock_gettime(CLOCK_MONOTONIC, &after);
+ total.tv_sec += after.tv_sec - before.tv_sec;
+ // Use auto instead of long to avoid the google-runtime-int warning.
+ auto deltaNs = after.tv_nsec - before.tv_nsec;
+ if (deltaNs < 0) {
+ deltaNs += 1000000000;
+ total.tv_sec--;
+ }
+ if ((total.tv_nsec += deltaNs) >= 1000000000) {
+ total.tv_nsec -= 1000000000;
+ total.tv_sec++;
+ }
+ before = after;
+ }
+ switch (error) {
case 0: // normal wakeup by server, or by binderDied()
case EWOULDBLOCK: // benign race condition with server
case EINTR: // wait was interrupted by signal or other spurious wakeup
case ETIMEDOUT: // time-out expired
break;
default:
- status = errno;
+ status = error;
ALOGE("%s unexpected error %s", __func__, strerror(status));
goto end;
}
@@ -747,7 +770,7 @@
int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
if (!(old & CBLK_FUTEX_WAKE)) {
(void) syscall(__NR_futex, &cblk->mFutex,
- mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);
+ mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, INT_MAX);
}
}
mFlushed += (newFront - front) & mask;
@@ -917,7 +940,7 @@
int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
if (!(old & CBLK_FUTEX_WAKE)) {
(void) syscall(__NR_futex, &cblk->mFutex,
- mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);
+ mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, INT_MAX);
}
}
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index 4c3955a..fc37575 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -293,7 +293,7 @@
void getReportedSurroundFormats(inout Int count,
out AudioFormat[] formats);
- AudioFormat[] getHwOffloadEncodingFormatsSupportedForA2DP();
+ AudioFormat[] getHwOffloadFormatsSupportedForBluetoothMedia(int /* audio_devices_t */ device);
void setSurroundFormatEnabled(AudioFormat audioFormat, boolean enabled);
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 8ba23ad..a2cfb2b 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -415,8 +415,8 @@
static status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
- static status_t getHwOffloadEncodingFormatsSupportedForA2DP(
- std::vector<audio_format_t> *formats);
+ static status_t getHwOffloadFormatsSupportedForBluetoothMedia(
+ audio_devices_t device, std::vector<audio_format_t> *formats);
// numSurroundFormats holds the maximum number of formats and bool value allowed in the array.
// When numSurroundFormats is 0, surroundFormats and surroundFormatsEnabled will not be
diff --git a/media/libaudiofoundation/AudioContainers.cpp b/media/libaudiofoundation/AudioContainers.cpp
index 31257d5..3df9378 100644
--- a/media/libaudiofoundation/AudioContainers.cpp
+++ b/media/libaudiofoundation/AudioContainers.cpp
@@ -63,6 +63,13 @@
return audioDeviceInAllUsbSet;
}
+const DeviceTypeSet& getAudioDeviceOutAllBleSet() {
+ static const DeviceTypeSet audioDeviceOutAllBleSet = DeviceTypeSet(
+ std::begin(AUDIO_DEVICE_OUT_ALL_BLE_ARRAY),
+ std::end(AUDIO_DEVICE_OUT_ALL_BLE_ARRAY));
+ return audioDeviceOutAllBleSet;
+}
+
bool deviceTypesToString(const DeviceTypeSet &deviceTypes, std::string &str) {
if (deviceTypes.empty()) {
str = "Empty device types";
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index 204b365..60b42fb 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -40,6 +40,7 @@
const DeviceTypeSet& getAudioDeviceOutAllUsbSet();
const DeviceTypeSet& getAudioDeviceInAllSet();
const DeviceTypeSet& getAudioDeviceInAllUsbSet();
+const DeviceTypeSet& getAudioDeviceOutAllBleSet();
template<typename T>
static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
diff --git a/media/libaudiohal/FactoryHalHidl.cpp b/media/libaudiohal/FactoryHalHidl.cpp
index e420d07..c19d2c2 100644
--- a/media/libaudiohal/FactoryHalHidl.cpp
+++ b/media/libaudiohal/FactoryHalHidl.cpp
@@ -94,7 +94,7 @@
} // namespace
void* createPreferredImpl(const std::string& package, const std::string& interface) {
- for (auto version = detail::sAudioHALVersions; version != nullptr; ++version) {
+ for (auto version = detail::sAudioHALVersions; *version != nullptr; ++version) {
void* rawInterface = nullptr;
if (hasHalService(package, *version, interface)
&& createHalService(*version, interface, &rawInterface)) {
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
index 1eadd27..ccef5ab 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
@@ -135,7 +135,6 @@
LVM_UINT32 fs =
(LVM_UINT32)LVEQNB_SampleRateTab[(LVM_UINT16)pParams->SampleRate]; /* Sample rate */
LVM_UINT32 fc; /* Filter centre frequency */
- LVM_INT16 QFactor; /* Filter Q factor */
pInstance->NBands = pParams->NBands;
@@ -144,7 +143,6 @@
* Get the filter settings
*/
fc = (LVM_UINT32)pParams->pBandDefinition[i].Frequency; /* Get the band centre frequency */
- QFactor = (LVM_INT16)pParams->pBandDefinition[i].QFactor; /* Get the band Q factor */
pInstance->pBiquadType[i] = LVEQNB_SinglePrecision_Float; /* Default to single precision */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
index 8e63502..ffed6d4 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
@@ -421,7 +421,6 @@
* Intermediate variables and temporary values
*/
LVM_FLOAT T0;
- LVM_FLOAT D;
LVM_FLOAT A0;
LVM_FLOAT B1;
LVM_FLOAT B2;
@@ -444,9 +443,6 @@
* Calculating the intermediate values
*/
T0 = Frequency * LVPSA_Float_TwoPiOnFsTable[Fs]; /* T0 = 2 * Pi * Fc / Fs */
- D = 3200; /* Floating point value 1.000000 (1*100*2^5) */
- /* Force D = 1 : the function was originally used for a peaking filter.
- The D parameter do not exist for a BandPass filter coefficients */
/*
* Calculate the B2 coefficient
@@ -535,7 +531,6 @@
* Intermediate variables and temporary values
*/
LVM_FLOAT T0;
- LVM_FLOAT D;
LVM_FLOAT A0;
LVM_FLOAT B1;
LVM_FLOAT B2;
@@ -558,9 +553,6 @@
* Calculating the intermediate values
*/
T0 = Frequency * LVPSA_Float_TwoPiOnFsTable[Fs]; /* T0 = 2 * Pi * Fc / Fs */
- D = 3200; /* Floating point value 1.000000 (1*100*2^5) */
- /* Force D = 1 : the function was originally used for a peaking filter.
- The D parameter do not exist for a BandPass filter coefficients */
/*
* Calculate the B2 coefficient
diff --git a/media/libeffects/preprocessing/.clang-format b/media/libeffects/preprocessing/.clang-format
deleted file mode 120000
index f1b4f69..0000000
--- a/media/libeffects/preprocessing/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../build/soong/scripts/system-clang-format
\ No newline at end of file
diff --git a/media/libeffects/preprocessing/tests/correlation.cpp b/media/libeffects/preprocessing/tests/correlation.cpp
index eb56fc3..0853673 100644
--- a/media/libeffects/preprocessing/tests/correlation.cpp
+++ b/media/libeffects/preprocessing/tests/correlation.cpp
@@ -36,7 +36,7 @@
const int16_t* sigY, int len,
int16_t enableCrossCorr) {
float maxCorrVal = 0.f, prevCorrVal = 0.f;
- int delay = 0, peakIndex = 0, flag = 0;
+ int peakIndex = 0, flag = 0;
int loopLim = (1 == enableCrossCorr) ? len : kMinLoopLimitValue;
std::vector<int> peakIndexVect(kNumPeaks, 0);
std::vector<float> peakValueVect(kNumPeaks, 0.f);
@@ -47,7 +47,6 @@
}
corrVal /= len - i;
if (corrVal > maxCorrVal) {
- delay = i;
maxCorrVal = corrVal;
}
// Correlation peaks are expected to be observed at equal intervals. The interval length is
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
index 273d91c..fcac551 100644
--- a/media/libheif/HeifDecoderImpl.cpp
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -15,6 +15,7 @@
*/
//#define LOG_NDEBUG 0
+#include "include/HeifDecoderAPI.h"
#define LOG_TAG "HeifDecoderImpl"
#include "HeifDecoderImpl.h"
@@ -464,7 +465,7 @@
}
bool HeifDecoderImpl::setOutputColor(HeifColorFormat heifColor) {
- if (heifColor == mOutputColor) {
+ if (heifColor == (HeifColorFormat)mOutputColor) {
return true;
}
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index e98d7d8..9c1b563 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -378,12 +378,12 @@
],
static_libs: [
- "resourcemanager_aidl_interface-ndk_platform",
+ "resourcemanager_aidl_interface-ndk",
"framework-permission-aidl-cpp",
],
export_static_lib_headers: [
- "resourcemanager_aidl_interface-ndk_platform",
+ "resourcemanager_aidl_interface-ndk",
"framework-permission-aidl-cpp",
],
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 1c9b9e4..5215c1b 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -949,6 +949,9 @@
mVideoWidth = ext1;
mVideoHeight = ext2;
break;
+ case MEDIA_STARTED:
+ ALOGV("Received media started message");
+ break;
case MEDIA_NOTIFY_TIME:
ALOGV("Received notify time message");
break;
diff --git a/media/libmedia/xsd/vts/OWNERS b/media/libmedia/xsd/vts/OWNERS
new file mode 100644
index 0000000..9af2eba
--- /dev/null
+++ b/media/libmedia/xsd/vts/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 151862
+sundongahn@google.com
diff --git a/media/libmediahelper/Android.bp b/media/libmediahelper/Android.bp
index 9b54199..a433fc6 100644
--- a/media/libmediahelper/Android.bp
+++ b/media/libmediahelper/Android.bp
@@ -20,7 +20,7 @@
},
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth.updatable",
+ "com.android.bluetooth",
"com.android.media",
"com.android.media.swcodec",
],
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index f55678d..c416a51 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -65,6 +65,7 @@
"libstagefright_foundation",
"libstagefright_httplive",
"libutils",
+ "packagemanager_aidl-cpp",
],
header_libs: [
diff --git a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
index 2aabd53..8c86e16 100644
--- a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
@@ -225,10 +225,26 @@
"media.stagefright.thumbnail.prefer_hw_codecs", false);
uint32_t flags = preferhw ? 0 : MediaCodecList::kPreferSoftwareCodecs;
Vector<AString> matchingCodecs;
+ sp<AMessage> format = new AMessage;
+ status_t err = convertMetaDataToMessage(trackMeta, &format);
+ if (err != OK) {
+ format = NULL;
+ }
+
+ // If decoding thumbnail check decoder supports thumbnail dimensions instead
+ int32_t thumbHeight, thumbWidth;
+ if (thumbnail && format != NULL
+ && trackMeta->findInt32(kKeyThumbnailHeight, &thumbHeight)
+ && trackMeta->findInt32(kKeyThumbnailWidth, &thumbWidth)) {
+ format->setInt32("height", thumbHeight);
+ format->setInt32("width", thumbWidth);
+ }
+
MediaCodecList::findMatchingCodecs(
mime,
false, /* encoder */
flags,
+ format,
&matchingCodecs);
for (size_t i = 0; i < matchingCodecs.size(); ++i) {
@@ -348,11 +364,18 @@
bool preferhw = property_get_bool(
"media.stagefright.thumbnail.prefer_hw_codecs", false);
uint32_t flags = preferhw ? 0 : MediaCodecList::kPreferSoftwareCodecs;
+ sp<AMessage> format = new AMessage;
+ status_t err = convertMetaDataToMessage(trackMeta, &format);
+ if (err != OK) {
+ format = NULL;
+ }
+
Vector<AString> matchingCodecs;
MediaCodecList::findMatchingCodecs(
mime,
false, /* encoder */
flags,
+ format,
&matchingCodecs);
for (size_t i = 0; i < matchingCodecs.size(); ++i) {
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index bffd7b3..6347b7a 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -16,6 +16,8 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "StagefrightRecorder"
+#define ATRACE_TAG ATRACE_TAG_VIDEO
+#include <utils/Trace.h>
#include <inttypes.h>
// TODO/workaround: including base logging now as it conflicts with ADebug.h
// and it must be included first.
@@ -1856,6 +1858,7 @@
// Set up the appropriate MediaSource depending on the chosen option
status_t StagefrightRecorder::setupMediaSource(
sp<MediaSource> *mediaSource) {
+ ATRACE_CALL();
if (mVideoSource == VIDEO_SOURCE_DEFAULT
|| mVideoSource == VIDEO_SOURCE_CAMERA) {
sp<CameraSource> cameraSource;
@@ -1936,6 +1939,7 @@
status_t StagefrightRecorder::setupVideoEncoder(
const sp<MediaSource> &cameraSource,
sp<MediaCodecSource> *source) {
+ ATRACE_CALL();
source->clear();
sp<AMessage> format = new AMessage();
@@ -2114,6 +2118,7 @@
}
status_t StagefrightRecorder::setupAudioEncoder(const sp<MediaWriter>& writer) {
+ ATRACE_CALL();
status_t status = BAD_VALUE;
if (OK != (status = checkAudioEncoderCapabilities())) {
return status;
diff --git a/media/libmediaplayerservice/tests/Android.bp b/media/libmediaplayerservice/tests/Android.bp
index 98626fd..99202b8 100644
--- a/media/libmediaplayerservice/tests/Android.bp
+++ b/media/libmediaplayerservice/tests/Android.bp
@@ -30,7 +30,7 @@
],
static_libs: [
- "resourcemanager_aidl_interface-ndk_platform",
+ "resourcemanager_aidl_interface-ndk",
],
include_dirs: [
diff --git a/media/libmediatranscoding/Android.bp b/media/libmediatranscoding/Android.bp
index 042850c..937650f 100644
--- a/media/libmediatranscoding/Android.bp
+++ b/media/libmediatranscoding/Android.bp
@@ -106,8 +106,8 @@
export_include_dirs: ["include"],
static_libs: [
- "mediatranscoding_aidl_interface-ndk_platform",
- "resourceobserver_aidl_interface-V1-ndk_platform",
+ "mediatranscoding_aidl_interface-ndk",
+ "resourceobserver_aidl_interface-V1-ndk",
"libstatslog_media",
],
diff --git a/media/libmediatranscoding/OWNERS b/media/libmediatranscoding/OWNERS
index b08d573..a4393a7 100644
--- a/media/libmediatranscoding/OWNERS
+++ b/media/libmediatranscoding/OWNERS
@@ -1,5 +1,4 @@
-chz@google.com
-gokrishnan@google.com
-hkuang@google.com
-lnilsson@google.com
-pawin@google.com
+# Bug component: 761430
+
+# go/android-fwk-media-solutions for info on areas of ownership.
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/media/libmediatranscoding/include/media/ControllerClientInterface.h b/media/libmediatranscoding/include/media/ControllerClientInterface.h
index 9311e2e..ea63da8 100644
--- a/media/libmediatranscoding/include/media/ControllerClientInterface.h
+++ b/media/libmediatranscoding/include/media/ControllerClientInterface.h
@@ -66,7 +66,7 @@
* Returns false if the session doesn't exist, or the client is already requesting the
* session. Returns true otherwise.
*/
- virtual bool addClientUid(ClientIdType clientId, SessionIdType sessionId, uid_t clientUid);
+ virtual bool addClientUid(ClientIdType clientId, SessionIdType sessionId, uid_t clientUid) = 0;
/**
* Retrieves the (unsorted) list of all clients requesting the session identified by
@@ -81,7 +81,7 @@
* Returns false if the session doesn't exist. Returns true otherwise.
*/
virtual bool getClientUids(ClientIdType clientId, SessionIdType sessionId,
- std::vector<int32_t>* out_clientUids);
+ std::vector<int32_t>* out_clientUids) = 0;
protected:
virtual ~ControllerClientInterface() = default;
diff --git a/media/libmediatranscoding/tests/Android.bp b/media/libmediatranscoding/tests/Android.bp
index 603611a..7a6980f 100644
--- a/media/libmediatranscoding/tests/Android.bp
+++ b/media/libmediatranscoding/tests/Android.bp
@@ -31,7 +31,7 @@
],
static_libs: [
- "mediatranscoding_aidl_interface-ndk_platform",
+ "mediatranscoding_aidl_interface-ndk",
"libmediatranscoding",
],
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 1aa1848..a4fbbbc 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -3304,10 +3304,12 @@
if (err != OK) {
ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
sidebandHandle, err);
- return err;
}
- return OK;
+ native_handle_close(sidebandHandle);
+ native_handle_delete(sidebandHandle);
+
+ return err;
}
status_t ACodec::setVideoPortFormatType(
@@ -5395,21 +5397,21 @@
err = mOMXNode->getParameter(
(OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
&presentation, sizeof(presentation));
- if (err != OK) {
- return err;
+ if (err == OK) {
+ notify->setInt32("aac-encoded-target-level",
+ presentation.nEncodedTargetLevel);
+ notify->setInt32("aac-drc-cut-level", presentation.nDrcCut);
+ notify->setInt32("aac-drc-boost-level", presentation.nDrcBoost);
+ notify->setInt32("aac-drc-heavy-compression",
+ presentation.nHeavyCompression);
+ notify->setInt32("aac-target-ref-level",
+ presentation.nTargetReferenceLevel);
+ notify->setInt32("aac-drc-effect-type",
+ presentation.nDrcEffectType);
+ notify->setInt32("aac-drc-album-mode", presentation.nDrcAlbumMode);
+ notify->setInt32("aac-drc-output-loudness",
+ presentation.nDrcOutputLoudness);
}
- notify->setInt32("aac-encoded-target-level",
- presentation.nEncodedTargetLevel);
- notify->setInt32("aac-drc-cut-level", presentation.nDrcCut);
- notify->setInt32("aac-drc-boost-level", presentation.nDrcBoost);
- notify->setInt32("aac-drc-heavy-compression",
- presentation.nHeavyCompression);
- notify->setInt32("aac-target-ref-level",
- presentation.nTargetReferenceLevel);
- notify->setInt32("aac-drc-effect-type", presentation.nDrcEffectType);
- notify->setInt32("aac-drc-album-mode", presentation.nDrcAlbumMode);
- notify->setInt32("aac-drc-output-loudness",
- presentation.nDrcOutputLoudness);
}
}
break;
@@ -5431,6 +5433,7 @@
notify->setInt32("channel-count", params.nChannels);
notify->setInt32("sample-rate", params.nSampleRate);
notify->setInt32("bitrate", params.nBitRate);
+ notify->setInt32("aac-profile", params.eAACProfile);
break;
}
@@ -9205,4 +9208,19 @@
return OK;
}
+status_t ACodec::querySupportedParameters(std::vector<std::string> *names) {
+ if (!names) {
+ return BAD_VALUE;
+ }
+ return OK;
+}
+
+status_t ACodec::subscribeToParameters([[maybe_unused]] const std::vector<std::string> &names) {
+ return OK;
+}
+
+status_t ACodec::unsubscribeFromParameters([[maybe_unused]] const std::vector<std::string> &names) {
+ return OK;
+}
+
} // namespace android
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index a052a70..e47e7ff 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -109,6 +109,7 @@
srcs: [
"CodecBase.cpp",
+ "DataConverter.cpp",
"FrameRenderTracker.cpp",
"MediaCodecListWriter.cpp",
"SkipCutBuffer.cpp",
@@ -125,6 +126,7 @@
],
shared_libs: [
+ "libaudioutils",
"libgui",
"libhidlallocatorutils",
"liblog",
@@ -266,7 +268,6 @@
"CallbackMediaSource.cpp",
"CameraSource.cpp",
"CameraSourceTimeLapse.cpp",
- "DataConverter.cpp",
"FrameDecoder.cpp",
"HevcUtils.cpp",
"InterfaceUtils.cpp",
@@ -340,6 +341,7 @@
"android.hardware.media.omx@1.0",
"framework-permission-aidl-cpp",
"libaudioclient_aidl_conversion",
+ "packagemanager_aidl-cpp",
],
static_libs: [
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index b513e45..9f86544 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -262,13 +262,10 @@
}
bool isHDR(const sp<AMessage> &format) {
- uint32_t standard, range, transfer;
+ uint32_t standard, transfer;
if (!format->findInt32("color-standard", (int32_t*)&standard)) {
standard = 0;
}
- if (!format->findInt32("color-range", (int32_t*)&range)) {
- range = 0;
- }
if (!format->findInt32("color-transfer", (int32_t*)&transfer)) {
transfer = 0;
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index c03236a..2851dc4 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -3185,8 +3185,11 @@
mediametrics_setInt32(mMetricsHandle, kCodecSecure, 0);
}
- if (mIsVideo) {
- // audio codec is currently ignored.
+ MediaCodecInfo::Attributes attr = mCodecInfo
+ ? mCodecInfo->getAttributes()
+ : MediaCodecInfo::Attributes(0);
+ if (!(attr & MediaCodecInfo::kFlagIsSoftwareOnly)) {
+ // software codec is currently ignored.
mResourceManagerProxy->addResource(
MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo));
}
@@ -3502,6 +3505,20 @@
case kWhatDrainThisBuffer:
{
+ if ((mFlags & kFlagUseBlockModel) == 0 && mTunneled) {
+ sp<RefBase> obj;
+ CHECK(msg->findObject("buffer", &obj));
+ sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
+ if (mFlags & kFlagIsAsync) {
+ // In asynchronous mode, output format change is processed immediately.
+ handleOutputFormatChangeIfNeeded(buffer);
+ } else {
+ postActivityNotificationIfPossible();
+ }
+ mBufferChannel->discardBuffer(buffer);
+ break;
+ }
+
/* size_t index = */updateBuffers(kPortIndexOutput, msg);
if (mState == FLUSHING
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 6243828..2ffe728 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -509,6 +509,29 @@
}
}
}
+
+ int32_t profile = -1;
+ if (format->findInt32("profile", &profile)) {
+ int32_t level = -1;
+ format->findInt32("level", &level);
+ Vector<MediaCodecInfo::ProfileLevel> profileLevels;
+ capabilities->getSupportedProfileLevels(&profileLevels);
+ auto it = profileLevels.begin();
+ for (; it != profileLevels.end(); ++it) {
+ if (profile != it->mProfile) {
+ continue;
+ }
+ if (level > -1 && level > it->mLevel) {
+ continue;
+ }
+ break;
+ }
+
+ if (it == profileLevels.end()) {
+ ALOGV("Codec does not support profile %d with level %d", profile, level);
+ return false;
+ }
+ }
}
// haven't found a reason to discard this one
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 0107c32..b07f8f7 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -943,10 +943,17 @@
sp<MediaCodecBuffer> outbuf;
status_t err = mEncoder->getOutputBuffer(index, &outbuf);
- if (err != OK || outbuf == NULL || outbuf->data() == NULL
- || outbuf->size() == 0) {
+ if (err != OK || outbuf == NULL || outbuf->data() == NULL) {
signalEOS();
break;
+ } else if (outbuf->size() == 0) {
+ // Zero length CSD buffers are not treated as an error
+ if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) {
+ mEncoder->releaseOutputBuffer(index);
+ } else {
+ signalEOS();
+ }
+ break;
}
MediaBufferBase *mbuf = new MediaBuffer(outbuf->size());
diff --git a/media/libstagefright/SkipCutBuffer.cpp b/media/libstagefright/SkipCutBuffer.cpp
index ee9016d..de91533 100644
--- a/media/libstagefright/SkipCutBuffer.cpp
+++ b/media/libstagefright/SkipCutBuffer.cpp
@@ -145,7 +145,19 @@
if (available < num) {
int32_t newcapacity = mCapacity + (num - available);
char * newbuffer = new char[newcapacity];
- memcpy(newbuffer, mCutBuffer, mCapacity);
+ if (mWriteHead < mReadHead) {
+ // data isn't continuous, need to memcpy twice
+ // to move previous data to new buffer.
+ size_t copyLeft = mCapacity - mReadHead;
+ memcpy(newbuffer, mCutBuffer + mReadHead, copyLeft);
+ memcpy(newbuffer + copyLeft, mCutBuffer, mWriteHead);
+ mReadHead = 0;
+ mWriteHead += copyLeft;
+ } else {
+ memcpy(newbuffer, mCutBuffer + mReadHead, mWriteHead - mReadHead);
+ mWriteHead -= mReadHead;
+ mReadHead = 0;
+ }
delete [] mCutBuffer;
mCapacity = newcapacity;
mCutBuffer = newbuffer;
diff --git a/media/libstagefright/TEST_MAPPING b/media/libstagefright/TEST_MAPPING
index 7ce2968..7d4e168 100644
--- a/media/libstagefright/TEST_MAPPING
+++ b/media/libstagefright/TEST_MAPPING
@@ -20,13 +20,35 @@
},
{
"exclude-annotation": "android.platform.test.annotations.RequiresDevice"
+ }
+ ]
+ },
+ {
+ "name": "CtsMediaAudioTestCases",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
},
// TODO: b/149314419
{
- "exclude-filter": "android.media.cts.AudioPlaybackCaptureTest"
+ "exclude-filter": "android.media.audio.cts.AudioPlaybackCaptureTest"
},
{
- "exclude-filter": "android.media.cts.AudioRecordTest"
+ "exclude-filter": "android.media.audio.cts.AudioRecordTest"
+ }
+ ]
+ },
+ {
+ "name": "CtsMediaPlayerTestCases",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
}
]
}
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 4c18f87..a6df5bb 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -1759,24 +1759,39 @@
if (mime.startsWith("video/") || mime.startsWith("image/")) {
int32_t width;
int32_t height;
- if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
- meta->setInt32(kKeyWidth, width);
- meta->setInt32(kKeyHeight, height);
- } else {
+ if (!msg->findInt32("width", &width) || !msg->findInt32("height", &height)) {
ALOGV("did not find width and/or height");
return BAD_VALUE;
}
+ if (width <= 0 || height <= 0) {
+ ALOGE("Invalid value of width: %d and/or height: %d", width, height);
+ return BAD_VALUE;
+ }
+ meta->setInt32(kKeyWidth, width);
+ meta->setInt32(kKeyHeight, height);
- int32_t sarWidth, sarHeight;
- if (msg->findInt32("sar-width", &sarWidth)
- && msg->findInt32("sar-height", &sarHeight)) {
+ int32_t sarWidth = -1, sarHeight = -1;
+ bool foundWidth, foundHeight;
+ foundWidth = msg->findInt32("sar-width", &sarWidth);
+ foundHeight = msg->findInt32("sar-height", &sarHeight);
+ if (foundWidth || foundHeight) {
+ if (sarWidth <= 0 || sarHeight <= 0) {
+ ALOGE("Invalid value of sarWidth: %d and/or sarHeight: %d", sarWidth, sarHeight);
+ return BAD_VALUE;
+ }
meta->setInt32(kKeySARWidth, sarWidth);
meta->setInt32(kKeySARHeight, sarHeight);
}
- int32_t displayWidth, displayHeight;
- if (msg->findInt32("display-width", &displayWidth)
- && msg->findInt32("display-height", &displayHeight)) {
+ int32_t displayWidth = -1, displayHeight = -1;
+ foundWidth = msg->findInt32("display-width", &displayWidth);
+ foundHeight = msg->findInt32("display-height", &displayHeight);
+ if (foundWidth || foundHeight) {
+ if (displayWidth <= 0 || displayHeight <= 0) {
+ ALOGE("Invalid value of displayWidth: %d and/or displayHeight: %d",
+ displayWidth, displayHeight);
+ return BAD_VALUE;
+ }
meta->setInt32(kKeyDisplayWidth, displayWidth);
meta->setInt32(kKeyDisplayHeight, displayHeight);
}
@@ -1786,17 +1801,29 @@
if (msg->findInt32("is-default", &isPrimary) && isPrimary) {
meta->setInt32(kKeyTrackIsDefault, 1);
}
- int32_t tileWidth, tileHeight, gridRows, gridCols;
- if (msg->findInt32("tile-width", &tileWidth)) {
+ int32_t tileWidth = -1, tileHeight = -1;
+ foundWidth = msg->findInt32("tile-width", &tileWidth);
+ foundHeight = msg->findInt32("tile-height", &tileHeight);
+ if (foundWidth || foundHeight) {
+ if (tileWidth <= 0 || tileHeight <= 0) {
+ ALOGE("Invalid value of tileWidth: %d and/or tileHeight: %d",
+ tileWidth, tileHeight);
+ return BAD_VALUE;
+ }
meta->setInt32(kKeyTileWidth, tileWidth);
- }
- if (msg->findInt32("tile-height", &tileHeight)) {
meta->setInt32(kKeyTileHeight, tileHeight);
}
- if (msg->findInt32("grid-rows", &gridRows)) {
+ int32_t gridRows = -1, gridCols = -1;
+ bool foundRows, foundCols;
+ foundRows = msg->findInt32("grid-rows", &gridRows);
+ foundCols = msg->findInt32("grid-cols", &gridCols);
+ if (foundRows || foundCols) {
+ if (gridRows <= 0 || gridCols <= 0) {
+ ALOGE("Invalid value of gridRows: %d and/or gridCols: %d",
+ gridRows, gridCols);
+ return BAD_VALUE;
+ }
meta->setInt32(kKeyGridRows, gridRows);
- }
- if (msg->findInt32("grid-cols", &gridCols)) {
meta->setInt32(kKeyGridCols, gridCols);
}
}
@@ -1812,6 +1839,14 @@
&cropTop,
&cropRight,
&cropBottom)) {
+ if (cropLeft < 0 || cropLeft > cropRight || cropRight >= width) {
+ ALOGE("Invalid value of cropLeft: %d and/or cropRight: %d", cropLeft, cropRight);
+ return BAD_VALUE;
+ }
+ if (cropTop < 0 || cropTop > cropBottom || cropBottom >= height) {
+ ALOGE("Invalid value of cropTop: %d and/or cropBottom: %d", cropTop, cropBottom);
+ return BAD_VALUE;
+ }
meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
}
@@ -1855,9 +1890,16 @@
ALOGV("did not find channel-count and/or sample-rate");
return BAD_VALUE;
}
+ // channel count can be zero in some cases like mpeg h
+ if (sampleRate <= 0 || numChannels < 0) {
+ ALOGE("Invalid value of channel-count: %d and/or sample-rate: %d",
+ numChannels, sampleRate);
+ return BAD_VALUE;
+ }
meta->setInt32(kKeyChannelCount, numChannels);
meta->setInt32(kKeySampleRate, sampleRate);
int32_t bitsPerSample;
+ // TODO:(b/204430952) add appropriate bound check for bitsPerSample
if (msg->findInt32("bits-per-sample", &bitsPerSample)) {
meta->setInt32(kKeyBitsPerSample, bitsPerSample);
}
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index fb6c4e2..bb1cb0b 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -354,7 +354,7 @@
}
if (mpeg4type->eProfile != OMX_VIDEO_MPEG4ProfileCore ||
- mpeg4type->eLevel != OMX_VIDEO_MPEG4Level2 ||
+ mpeg4type->eLevel > OMX_VIDEO_MPEG4Level2 ||
(mpeg4type->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) ||
mpeg4type->nBFrames != 0 ||
mpeg4type->nIDCVLCThreshold != 0 ||
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index c2114b3..5c99cc9 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -33,7 +33,7 @@
#include <media/stagefright/foundation/hexdump.h>
-#if !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
#include <binder/Parcel.h>
#endif
@@ -659,7 +659,7 @@
return s;
}
-#if !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
// static
sp<AMessage> AMessage::FromParcel(const Parcel &parcel, size_t maxNestingLevel) {
int32_t what = parcel.readInt32();
@@ -825,7 +825,7 @@
}
}
}
-#endif // !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#endif // defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
sp<AMessage> AMessage::changesFrom(const sp<const AMessage> &other, bool deep) const {
if (other == NULL) {
diff --git a/media/libstagefright/foundation/AString.cpp b/media/libstagefright/foundation/AString.cpp
index b1ed077..a5e0ff8 100644
--- a/media/libstagefright/foundation/AString.cpp
+++ b/media/libstagefright/foundation/AString.cpp
@@ -27,7 +27,7 @@
#include "ADebug.h"
#include "AString.h"
-#if !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
#include <binder/Parcel.h>
#endif
@@ -365,7 +365,7 @@
return !strcasecmp(mData + mSize - suffixLen, suffix);
}
-#if !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
// static
AString AString::FromParcel(const Parcel &parcel) {
size_t size = static_cast<size_t>(parcel.readInt32());
@@ -380,7 +380,7 @@
}
return err;
}
-#endif // !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#endif // defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
AString AStringPrintf(const char *format, ...) {
va_list ap;
diff --git a/media/libstagefright/foundation/MetaData.cpp b/media/libstagefright/foundation/MetaData.cpp
index 7f48cfd..77913d5 100644
--- a/media/libstagefright/foundation/MetaData.cpp
+++ b/media/libstagefright/foundation/MetaData.cpp
@@ -28,7 +28,7 @@
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MetaData.h>
-#if !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
#include <binder/Parcel.h>
#endif
@@ -48,7 +48,7 @@
MetaData::~MetaData() {
}
-#if !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
/* static */
sp<MetaData> MetaData::createFromParcel(const Parcel &parcel) {
diff --git a/media/libstagefright/foundation/MetaDataBase.cpp b/media/libstagefright/foundation/MetaDataBase.cpp
index 3f050ea..980eb22 100644
--- a/media/libstagefright/foundation/MetaDataBase.cpp
+++ b/media/libstagefright/foundation/MetaDataBase.cpp
@@ -28,7 +28,7 @@
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MetaDataBase.h>
-#if !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
#include <binder/Parcel.h>
#endif
@@ -452,7 +452,7 @@
}
}
-#if !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
status_t MetaDataBase::writeToParcel(Parcel &parcel) {
status_t ret;
size_t numItems = mInternalData->mItems.size();
@@ -532,7 +532,7 @@
ALOGW("no metadata in parcel");
return UNKNOWN_ERROR;
}
-#endif // !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
+#endif // defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
} // namespace android
diff --git a/media/libstagefright/httplive/Android.bp b/media/libstagefright/httplive/Android.bp
index 0b0acbf..7acf735 100644
--- a/media/libstagefright/httplive/Android.bp
+++ b/media/libstagefright/httplive/Android.bp
@@ -29,7 +29,6 @@
],
include_dirs: [
- "frameworks/av/media/libstagefright",
"frameworks/native/include/media/openmax",
],
@@ -65,6 +64,8 @@
header_libs: [
"libbase_headers",
+ "libstagefright_headers",
+ "libstagefright_httplive_headers",
],
static_libs: [
@@ -74,3 +75,8 @@
],
}
+
+cc_library_headers {
+ name: "libstagefright_httplive_headers",
+ export_include_dirs: ["."],
+}
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 3bad015..0d7cadd 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -23,7 +23,7 @@
#include "M3UParser.h"
#include "PlaylistFetcher.h"
-#include "mpeg2ts/AnotherPacketSource.h"
+#include <AnotherPacketSource.h>
#include <cutils/properties.h>
#include <media/MediaHTTPService.h>
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index 7a6d487..ceea41d 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -24,7 +24,7 @@
#include <utils/String8.h>
-#include "mpeg2ts/ATSParser.h"
+#include <ATSParser.h>
namespace android {
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index b23aa8a..907b326 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -24,9 +24,9 @@
#include "HTTPDownloader.h"
#include "LiveSession.h"
#include "M3UParser.h"
-#include "include/ID3.h"
-#include "mpeg2ts/AnotherPacketSource.h"
-#include "mpeg2ts/HlsSampleDecryptor.h"
+#include <ID3.h>
+#include <AnotherPacketSource.h>
+#include <HlsSampleDecryptor.h>
#include <datasource/DataURISource.h>
#include <media/stagefright/foundation/ABitReader.h>
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index 5d3f9c1..2e28164 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -21,7 +21,7 @@
#include <media/stagefright/foundation/AHandler.h>
#include <openssl/aes.h>
-#include "mpeg2ts/ATSParser.h"
+#include <ATSParser.h>
#include "LiveSession.h"
namespace android {
diff --git a/media/libstagefright/httplive/fuzzer/Android.bp b/media/libstagefright/httplive/fuzzer/Android.bp
new file mode 100644
index 0000000..14097b0
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/Android.bp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+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_media_libstagefright_httplive_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: [
+ "frameworks_av_media_libstagefright_httplive_license",
+ ],
+}
+
+cc_fuzz {
+ name: "httplive_fuzzer",
+ srcs: [
+ "httplive_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libstagefright_httplive",
+ "libstagefright_id3",
+ "libstagefright_metadatautils",
+ "libstagefright_mpeg2support",
+ "liblog",
+ "libcutils",
+ "libdatasource",
+ "libmedia",
+ "libstagefright",
+ "libutils",
+ ],
+ header_libs: [
+ "libbase_headers",
+ "libstagefright_foundation_headers",
+ "libstagefright_headers",
+ "libstagefright_httplive_headers",
+ ],
+ shared_libs: [
+ "libcrypto",
+ "libstagefright_foundation",
+ "libhidlbase",
+ "libhidlmemory",
+ "android.hidl.allocator@1.0",
+ ],
+ corpus: ["corpus/*"],
+ dictionary: "httplive_fuzzer.dict",
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ },
+}
diff --git a/media/libstagefright/httplive/fuzzer/README.md b/media/libstagefright/httplive/fuzzer/README.md
new file mode 100644
index 0000000..3a64ea4
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/README.md
@@ -0,0 +1,56 @@
+# Fuzzer for libstagefright_httplive
+
+## Plugin Design Considerations
+The fuzzer plugin for libstagefright_httplive is designed based on the understanding of the library and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data.Also, several .m3u8 files are hand-crafted and added to the corpus directory to increase the code coverage. This ensures more code paths are reached by the fuzzer.
+
+libstagefright_httplive supports the following parameters:
+1. Final Result (parameter name: `finalResult`)
+2. Flags (parameter name: `flags`)
+3. Time Us (parameter name: `timeUs`)
+4. Track Index (parameter name: `trackIndex`)
+5. Index (parameter name: `index`)
+6. Select (parameter name: `select`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `finalResult` | `-34` to `-1` | Value obtained from FuzzedDataProvider|
+| `flags` | `0` to `1` | Value obtained from FuzzedDataProvider|
+| `timeUs` | `0` to `10000000` | Value obtained from FuzzedDataProvider|
+| `trackIndex` | `UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
+| `index` | `UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
+| `select` | `True` to `False` | Value obtained from FuzzedDataProvider|
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the httplive module.
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build httplive_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) httplive_fuzzer
+```
+#### Steps to run
+To run on device
+```
+ $ adb push $ANDROID_PRODUCT_OUT/data/fuzz/$(TARGET_ARCH)/lib /data/fuzz/$(TARGET_ARCH)/lib
+ $ adb push $ANDROID_PRODUCT_OUT/data/fuzz/$(TARGET_ARCH)/httplive_fuzzer /data/fuzz/$(TARGET_ARCH)/httplive_fuzzer
+ $ adb shell /data/fuzz/${TARGET_ARCH}/httplive_fuzzer/httplive_fuzzer /data/fuzz/${TARGET_ARCH}/httplive_fuzzer/corpus
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/libstagefright/httplive/fuzzer/corpus/crypt.key b/media/libstagefright/httplive/fuzzer/corpus/crypt.key
new file mode 100644
index 0000000..f9d5d7f
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/crypt.key
@@ -0,0 +1,2 @@
+Û
+ÏüÐ5Ð_xïHÎ3
diff --git a/media/libstagefright/httplive/fuzzer/corpus/encrypted.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/encrypted.m3u8
new file mode 100644
index 0000000..32b0eac
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/encrypted.m3u8
@@ -0,0 +1,12 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:10
+#EXT-X-ALLOW-CACHE:YES
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXT-X-VERSION:3
+#EXT-X-MEDIA-SEQUENCE:1
+#EXT-X-KEY:METHOD=AES-128,URI="../../fuzz/arm64/httplive_fuzzer/corpus/crypt.key"
+#EXTINF:10.000,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXTINF:5.092,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXT-X-ENDLIST
diff --git a/media/libstagefright/httplive/fuzzer/corpus/hls.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/hls.m3u8
new file mode 100644
index 0000000..9338e04
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/hls.m3u8
@@ -0,0 +1,8 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:10
+#EXT-X-MEDIA-SEQUENCE:0
+#EXTINF:10, no desc
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXTINF:10, no desc
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence2.ts
+#EXT-X-ENDLIST
diff --git a/media/libstagefright/httplive/fuzzer/corpus/index1.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/index1.m3u8
new file mode 100644
index 0000000..e1eff58
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/index1.m3u8
@@ -0,0 +1,14 @@
+#EXTM3U
+#EXT-X-VERSION:4
+#EXT-X-TARGETDURATION:5
+#EXT-X-KEY:METHOD=NONE
+#EXT-X-DISCONTINUITY-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence0.ts
+#EXT-X-DISCONTINUITY
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence2.ts
+#EXT-X-ENDLIST
diff --git a/media/libstagefright/httplive/fuzzer/corpus/index2.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/index2.m3u8
new file mode 100644
index 0000000..37a0189
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/index2.m3u8
@@ -0,0 +1,6 @@
+#EXTM3U
+#EXT-X-INDEPENDENT-SEGMENTS
+#EXT-X-STREAM-INF:CLOSED-CAPTIONS=NONE,BANDWIDTH=165340,RESOLUTION=256x144,CODECS="mp4a.40.5,avc1.42c00b"
+https://non.existentsite.com/test-doesnt-dereference-these-paths/prog_index.m3u8
+#EXT-X-STREAM-INF:CLOSED-CAPTIONS=NONE,BANDWIDTH=344388,RESOLUTION=426x240,CODECS="mp4a.40.5,avc1.4d4015"
+https://non.existentsite.com/test-doesnt-dereference-these-paths/prog_index1.m3u8
diff --git a/media/libstagefright/httplive/fuzzer/corpus/index3.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/index3.m3u8
new file mode 100644
index 0000000..1b7f489
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/index3.m3u8
@@ -0,0 +1,13 @@
+#EXTM3U
+#EXT-X-VERSION:4
+#EXT-X-TARGETDURATION:5
+#EXT-X-KEY:METHOD=AES-128,URI="https://demo.unified-streaming.com/video/tears-of-steel/aes.key",IV=0X99b74007b6254e4bd1c6e03631cad15b
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXT-X-DISCONTINUITY
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence2.ts
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence3.ts
+#EXT-X-ENDLIST
diff --git a/media/libstagefright/httplive/fuzzer/corpus/index4.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/index4.m3u8
new file mode 100644
index 0000000..89ba37c
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/index4.m3u8
@@ -0,0 +1,15 @@
+#EXTM3U
+#EXT-X-VERSION:4
+#EXT-X-TARGETDURATION:5
+#EXT-X-KEY:METHOD=SAMPLE-AES,URI="data:text/plain;charset=utf-8,a4cd9995a1aa91e1",IV=0X99b74007b6254e4bd1c6e03631cad15b
+#EXT-X-DISCONTINUITY-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXT-X-DISCONTINUITY
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence0.ts
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXT-X-DISCONTINUITY
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence2.ts
+#EXT-X-ENDLIST
diff --git a/media/libstagefright/httplive/fuzzer/corpus/index5.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/index5.m3u8
new file mode 100644
index 0000000..2120de4
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/index5.m3u8
@@ -0,0 +1,14 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:11
+#EXT-X-KEY:METHOD=NONE
+#EXT-X-MEDIA-SEQUENCE:0
+#EXT-X-VERSION:4
+#EXTINF:10.0,
+#EXT-X-BYTERANGE:10@0
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXTINF:10.0,
+#EXT-X-BYTERANGE:20@10
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXTINF:10.0,
+#EXT-X-BYTERANGE:80
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
diff --git a/media/libstagefright/httplive/fuzzer/corpus/index6.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/index6.m3u8
new file mode 100644
index 0000000..588368a
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/index6.m3u8
@@ -0,0 +1,12 @@
+#EXTM3U
+#EXT-X-VERSION:4
+#EXT-X-TARGETDURATION:5
+#EXT-X-KEY:METHOD=AES-128,URI="data:text/plain;charset=utf-8,a4cd9995a1aa91e1",IV=0x30303030303030303030303030303030
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence2.ts
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence3.ts
+#EXT-X-ENDLIST
diff --git a/media/libstagefright/httplive/fuzzer/corpus/index7.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/index7.m3u8
new file mode 100644
index 0000000..b09948e
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/index7.m3u8
@@ -0,0 +1,46 @@
+#EXTM3U
+#EXT-X-VERSION:4
+## Created with Unified Streaming Platform (version=1.11.3-24438)
+#EXT-X-SESSION-KEY:METHOD=AES-128,URI="https://demo.unified-streaming.com/video/tears-of-steel/aes.key"
+
+# AUDIO groups
+#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-64",LANGUAGE="en",NAME="English",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="2"
+#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-128",LANGUAGE="en",NAME="English",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="2"
+
+# SUBTITLES groups
+#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="textstream",LANGUAGE="en",NAME="English",DEFAULT=YES,AUTOSELECT=YES,URI="tears-of-steel-aes-textstream_eng=1000.m3u8"
+#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="textstream",LANGUAGE="ru",NAME="Russian",AUTOSELECT=YES,URI="tears-of-steel-aes-textstream_rus=1000.m3u8"
+
+# variants
+#EXT-X-STREAM-INF:BANDWIDTH=494000,CODECS="mp4a.40.2,avc1.42C00D",RESOLUTION=224x100,FRAME-RATE=24,AUDIO="audio-aacl-64",SUBTITLES="textstream",CLOSED-CAPTIONS=NONE
+tears-of-steel-aes-audio_eng=64008-video_eng=401000.m3u8
+#EXT-X-STREAM-INF:BANDWIDTH=933000,CODECS="mp4a.40.2,avc1.42C016",RESOLUTION=448x200,FRAME-RATE=24,AUDIO="audio-aacl-128",SUBTITLES="textstream",CLOSED-CAPTIONS=NONE
+tears-of-steel-aes-audio_eng=128002-video_eng=751000.m3u8
+#EXT-X-STREAM-INF:BANDWIDTH=1198000,CODECS="mp4a.40.2,avc1.4D401F",RESOLUTION=784x350,FRAME-RATE=24,AUDIO="audio-aacl-128",SUBTITLES="textstream",CLOSED-CAPTIONS=NONE
+tears-of-steel-aes-audio_eng=128002-video_eng=1001000.m3u8
+#EXT-X-STREAM-INF:BANDWIDTH=1728000,CODECS="mp4a.40.2,avc1.640028",RESOLUTION=1680x750,FRAME-RATE=24,VIDEO-RANGE=SDR,AUDIO="audio-aacl-128",SUBTITLES="textstream",CLOSED-CAPTIONS=NONE
+tears-of-steel-aes-audio_eng=128002-video_eng=1501000.m3u8
+#EXT-X-STREAM-INF:BANDWIDTH=2469000,CODECS="mp4a.40.2,avc1.640028",RESOLUTION=1680x750,FRAME-RATE=24,VIDEO-RANGE=SDR,AUDIO="audio-aacl-128",SUBTITLES="textstream",CLOSED-CAPTIONS=NONE
+tears-of-steel-aes-audio_eng=128002-video_eng=2200000.m3u8
+
+# variants
+#EXT-X-STREAM-INF:BANDWIDTH=1025000,CODECS="mp4a.40.2,hvc1.1.6.L150.90",RESOLUTION=1680x750,FRAME-RATE=24,VIDEO-RANGE=SDR,AUDIO="audio-aacl-64",SUBTITLES="textstream",CLOSED-CAPTIONS=NONE
+tears-of-steel-aes-audio_eng=64008-video_eng_1=902000.m3u8
+#EXT-X-STREAM-INF:BANDWIDTH=1368000,CODECS="mp4a.40.2,hvc1.1.6.L150.90",RESOLUTION=2576x1150,FRAME-RATE=24,VIDEO-RANGE=SDR,AUDIO="audio-aacl-128",SUBTITLES="textstream",CLOSED-CAPTIONS=NONE
+tears-of-steel-aes-audio_eng=128002-video_eng_1=1161000.m3u8
+#EXT-X-STREAM-INF:BANDWIDTH=1815000,CODECS="mp4a.40.2,hvc1.1.6.L150.90",RESOLUTION=3360x1500,FRAME-RATE=24,VIDEO-RANGE=SDR,AUDIO="audio-aacl-128",SUBTITLES="textstream",CLOSED-CAPTIONS=NONE
+tears-of-steel-aes-audio_eng=128002-video_eng_1=1583000.m3u8
+
+# variants
+#EXT-X-STREAM-INF:BANDWIDTH=69000,CODECS="mp4a.40.2",AUDIO="audio-aacl-64",SUBTITLES="textstream"
+tears-of-steel-aes-audio_eng=64008.m3u8
+#EXT-X-STREAM-INF:BANDWIDTH=137000,CODECS="mp4a.40.2",AUDIO="audio-aacl-128",SUBTITLES="textstream"
+tears-of-steel-aes-audio_eng=128002.m3u8
+
+# keyframes
+#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=54000,CODECS="avc1.42C00D",RESOLUTION=224x100,URI="keyframes/tears-of-steel-aes-video_eng=401000.m3u8"
+#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=100000,CODECS="avc1.42C016",RESOLUTION=448x200,URI="keyframes/tears-of-steel-aes-video_eng=751000.m3u8"
+#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=133000,CODECS="avc1.4D401F",RESOLUTION=784x350,URI="keyframes/tears-of-steel-aes-video_eng=1001000.m3u8"
+#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=120000,CODECS="hvc1.1.6.L150.90",RESOLUTION=1680x750,VIDEO-RANGE=SDR,URI="keyframes/tears-of-steel-aes-video_eng_1=902000.m3u8"
+#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=154000,CODECS="hvc1.1.6.L150.90",RESOLUTION=2576x1150,VIDEO-RANGE=SDR,URI="keyframes/tears-of-steel-aes-video_eng_1=1161000.m3u8"
+#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=210000,CODECS="hvc1.1.6.L150.90",RESOLUTION=3360x1500,VIDEO-RANGE=SDR,URI="keyframes/tears-of-steel-aes-video_eng_1=1583000.m3u8"
diff --git a/media/libstagefright/httplive/fuzzer/corpus/index8.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/index8.m3u8
new file mode 100644
index 0000000..353d589
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/index8.m3u8
@@ -0,0 +1,13 @@
+#EXTM3U
+#EXT-X-VERSION:5
+
+#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="English stereo",LANGUAGE="en",AUTOSELECT=YES,URI="../../fuzz/arm64/httplive_fuzzer/index1.m3u8"
+
+#EXT-X-STREAM-INF:BANDWIDTH=628000,CODECS="avc1.42c00d,mp4a.40.2",RESOLUTION=320x180,AUDIO="audio"
+../../fuzz/arm64/httplive_fuzzer/index1.m3u8
+#EXT-X-STREAM-INF:BANDWIDTH=928000,CODECS="avc1.42c00d,mp4a.40.2",RESOLUTION=480x270,AUDIO="audio"
+../../fuzz/arm64/httplive_fuzzer/index2.m3u8
+#EXT-X-STREAM-INF:BANDWIDTH=1728000,CODECS="avc1.42c00d,mp4a.40.2",RESOLUTION=640x360,AUDIO="audio"
+../../fuzz/arm64/httplive_fuzzer/index3.m3u8
+#EXT-X-STREAM-INF:BANDWIDTH=2528000,CODECS="avc1.42c00d,mp4a.40.2",RESOLUTION=960x540,AUDIO="audio"
+../../fuzz/arm64/httplive_fuzzer/index1.m3u8
diff --git a/media/libstagefright/httplive/fuzzer/corpus/prog_index.m3u8 b/media/libstagefright/httplive/fuzzer/corpus/prog_index.m3u8
new file mode 100644
index 0000000..eb88422
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/corpus/prog_index.m3u8
@@ -0,0 +1,17 @@
+#EXTM3U
+#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",LANGUAGE="eng",NAME="English",AUTOSELECT=YES,DEFAULT=YES,URI="corpus/index1.m3u8"
+#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",LANGUAGE="fre",NAME="Français",AUTOSELECT=YES,DEFAULT=NO,URI="corpus/index1.m3u8"
+#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",LANGUAGE="sp",NAME="Espanol",AUTOSELECT=YES,DEFAULT=NO,URI="corpus/index1.m3u8"
+#EXT-X-VERSION:4
+#EXT-X-TARGETDURATION:5
+#EXT-X-KEY:METHOD=NONE
+#EXT-X-DISCONTINUITY-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXT-X-DISCONTINUITY
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXTINF:5,
+https://non.existentsite.com/test-doesnt-dereference-these-paths/fileSequence1.ts
+#EXT-X-ENDLIST
diff --git a/media/libstagefright/httplive/fuzzer/httplive_fuzzer.cpp b/media/libstagefright/httplive/fuzzer/httplive_fuzzer.cpp
new file mode 100644
index 0000000..aa777b3
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/httplive_fuzzer.cpp
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2021 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 <fstream>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <LiveDataSource.h>
+#include <LiveSession.h>
+#include <media/MediaHTTPConnection.h>
+#include <media/MediaHTTPService.h>
+#include <media/mediaplayer_common.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/ALooperRoster.h>
+#include <string>
+#include <utils/Log.h>
+
+using namespace std;
+using namespace android;
+
+constexpr char kFileNamePrefix[] = "/data/local/tmp/httplive-";
+constexpr char kFileNameSuffix[] = ".m3u8";
+constexpr char kFileUrlPrefix[] = "file://";
+constexpr int64_t kOffSet = 0;
+constexpr int32_t kReadyMarkMs = 5000;
+constexpr int32_t kPrepareMarkMs = 1500;
+constexpr int32_t kErrorNoMax = -1;
+constexpr int32_t kErrorNoMin = -34;
+constexpr int32_t kMaxTimeUs = 1000;
+constexpr int32_t kRandomStringLength = 64;
+constexpr int32_t kRangeMin = 0;
+constexpr int32_t kRangeMax = 1000;
+
+constexpr LiveSession::StreamType kValidStreamType[] = {
+ LiveSession::STREAMTYPE_AUDIO, LiveSession::STREAMTYPE_VIDEO,
+ LiveSession::STREAMTYPE_SUBTITLES, LiveSession::STREAMTYPE_METADATA};
+
+constexpr MediaSource::ReadOptions::SeekMode kValidSeekMode[] = {
+ MediaSource::ReadOptions::SeekMode::SEEK_PREVIOUS_SYNC,
+ MediaSource::ReadOptions::SeekMode::SEEK_NEXT_SYNC,
+ MediaSource::ReadOptions::SeekMode::SEEK_CLOSEST_SYNC,
+ MediaSource::ReadOptions::SeekMode::SEEK_CLOSEST,
+ MediaSource::ReadOptions::SeekMode::SEEK_FRAME_INDEX};
+
+constexpr media_track_type kValidMediaTrackType[] = {
+ MEDIA_TRACK_TYPE_UNKNOWN, MEDIA_TRACK_TYPE_VIDEO,
+ MEDIA_TRACK_TYPE_AUDIO, MEDIA_TRACK_TYPE_TIMEDTEXT,
+ MEDIA_TRACK_TYPE_SUBTITLE, MEDIA_TRACK_TYPE_METADATA};
+
+struct TestAHandler : public AHandler {
+public:
+ TestAHandler(std::function<void()> signalEosFunction)
+ : mSignalEosFunction(signalEosFunction) {}
+ virtual ~TestAHandler() {}
+
+protected:
+ void onMessageReceived(const sp<AMessage> &msg) override {
+ int32_t what = -1;
+ msg->findInt32("what", &what);
+ switch (what) {
+ case LiveSession::kWhatError:
+ case LiveSession::kWhatPrepared:
+ case LiveSession::kWhatPreparationFailed: {
+ mSignalEosFunction();
+ break;
+ }
+ }
+ return;
+ }
+
+private:
+ std::function<void()> mSignalEosFunction;
+};
+
+struct TestMediaHTTPConnection : public MediaHTTPConnection {
+public:
+ TestMediaHTTPConnection() {}
+ virtual ~TestMediaHTTPConnection() {}
+
+ virtual bool connect(const char * /*uri*/,
+ const KeyedVector<String8, String8> * /*headers*/) {
+ return true;
+ }
+
+ virtual void disconnect() { return; }
+
+ virtual ssize_t readAt(off64_t /*offset*/, void * /*data*/, size_t size) {
+ return size;
+ }
+
+ virtual off64_t getSize() { return 0; }
+ virtual status_t getMIMEType(String8 * /*mimeType*/) { return NO_ERROR; }
+ virtual status_t getUri(String8 * /*uri*/) { return NO_ERROR; }
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(TestMediaHTTPConnection);
+};
+
+struct TestMediaHTTPService : public MediaHTTPService {
+public:
+ TestMediaHTTPService() {}
+ ~TestMediaHTTPService(){};
+
+ virtual sp<MediaHTTPConnection> makeHTTPConnection() {
+ mediaHTTPConnection = sp<TestMediaHTTPConnection>::make();
+ return mediaHTTPConnection;
+ }
+
+private:
+ sp<TestMediaHTTPConnection> mediaHTTPConnection = nullptr;
+ DISALLOW_EVIL_CONSTRUCTORS(TestMediaHTTPService);
+};
+
+class HttpLiveFuzzer {
+public:
+ void process(const uint8_t *data, size_t size);
+ void deInitLiveSession();
+ ~HttpLiveFuzzer() { deInitLiveSession(); }
+
+private:
+ void invokeLiveDataSource();
+ void createM3U8File(const uint8_t *data, size_t size);
+ void initLiveDataSource();
+ void invokeLiveSession();
+ void initLiveSession();
+ void invokeDequeueAccessUnit();
+ void invokeConnectAsync();
+ void invokeSeekTo();
+ void invokeGetConfig();
+ void signalEos();
+ string generateFileName();
+ sp<LiveDataSource> mLiveDataSource = nullptr;
+ sp<LiveSession> mLiveSession = nullptr;
+ sp<ALooper> mLiveLooper = nullptr;
+ sp<TestMediaHTTPService> httpService = nullptr;
+ sp<TestAHandler> mHandler = nullptr;
+ FuzzedDataProvider *mFDP = nullptr;
+ bool mEosReached = false;
+ std::mutex mDownloadCompleteMutex;
+ std::condition_variable mConditionalVariable;
+};
+
+string HttpLiveFuzzer::generateFileName() {
+ return kFileNamePrefix + to_string(getpid()) + kFileNameSuffix;
+}
+
+void HttpLiveFuzzer::createM3U8File(const uint8_t *data, size_t size) {
+ ofstream m3u8File;
+ string currentFileName = generateFileName();
+ m3u8File.open(currentFileName, ios::out | ios::binary);
+ m3u8File.write((char *)data, size);
+ m3u8File.close();
+}
+
+void HttpLiveFuzzer::initLiveDataSource() {
+ mLiveDataSource = sp<LiveDataSource>::make();
+}
+
+void HttpLiveFuzzer::invokeLiveDataSource() {
+ initLiveDataSource();
+ size_t size = mFDP->ConsumeIntegralInRange<size_t>(kRangeMin, kRangeMax);
+ sp<ABuffer> buffer = new ABuffer(size);
+ mLiveDataSource->queueBuffer(buffer);
+ uint8_t *data = new uint8_t[size];
+ mLiveDataSource->readAtNonBlocking(kOffSet, data, size);
+ int32_t finalResult = mFDP->ConsumeIntegralInRange(kErrorNoMin, kErrorNoMax);
+ mLiveDataSource->queueEOS(finalResult);
+ mLiveDataSource->reset();
+ mLiveDataSource->countQueuedBuffers();
+ mLiveDataSource->initCheck();
+ delete[] data;
+}
+
+void HttpLiveFuzzer::initLiveSession() {
+ ALooperRoster looperRoster;
+ mHandler =
+ sp<TestAHandler>::make(std::bind(&HttpLiveFuzzer::signalEos, this));
+ mLiveLooper = sp<ALooper>::make();
+ mLiveLooper->setName("http live");
+ mLiveLooper->start();
+ sp<AMessage> notify = sp<AMessage>::make(0, mHandler);
+ httpService = new TestMediaHTTPService();
+ uint32_t flags = mFDP->ConsumeIntegral<uint32_t>();
+ mLiveSession = sp<LiveSession>::make(notify, flags, httpService);
+ mLiveLooper->registerHandler(mLiveSession);
+ looperRoster.registerHandler(mLiveLooper, mHandler);
+}
+
+void HttpLiveFuzzer::invokeDequeueAccessUnit() {
+ LiveSession::StreamType stream = mFDP->PickValueInArray(kValidStreamType);
+ sp<ABuffer> buffer;
+ mLiveSession->dequeueAccessUnit(stream, &buffer);
+}
+
+void HttpLiveFuzzer::invokeSeekTo() {
+ int64_t timeUs = mFDP->ConsumeIntegralInRange<int64_t>(0, kMaxTimeUs);
+ MediaSource::ReadOptions::SeekMode mode =
+ mFDP->PickValueInArray(kValidSeekMode);
+ mLiveSession->seekTo(timeUs, mode);
+}
+
+void HttpLiveFuzzer::invokeGetConfig() {
+ mLiveSession->getTrackCount();
+ size_t trackIndex = mFDP->ConsumeIntegral<size_t>();
+ mLiveSession->getTrackInfo(trackIndex);
+ media_track_type type = mFDP->PickValueInArray(kValidMediaTrackType);
+ mLiveSession->getSelectedTrack(type);
+ sp<MetaData> meta;
+ LiveSession::StreamType stream = mFDP->PickValueInArray(kValidStreamType);
+ mLiveSession->getStreamFormatMeta(stream, &meta);
+ mLiveSession->getKeyForStream(stream);
+ if (stream != LiveSession::STREAMTYPE_SUBTITLES) {
+ mLiveSession->getSourceTypeForStream(stream);
+ }
+}
+
+void HttpLiveFuzzer::invokeConnectAsync() {
+ string currentFileName = generateFileName();
+ string url = kFileUrlPrefix + currentFileName;
+ string str_1 = mFDP->ConsumeRandomLengthString(kRandomStringLength);
+ string str_2 = mFDP->ConsumeRandomLengthString(kRandomStringLength);
+
+ KeyedVector<String8, String8> headers;
+ headers.add(String8(str_1.c_str()), String8(str_2.c_str()));
+ mLiveSession->connectAsync(url.c_str(), &headers);
+}
+
+void HttpLiveFuzzer::invokeLiveSession() {
+ initLiveSession();
+ BufferingSettings bufferingSettings;
+ bufferingSettings.mInitialMarkMs = kPrepareMarkMs;
+ bufferingSettings.mResumePlaybackMarkMs = kReadyMarkMs;
+ mLiveSession->setBufferingSettings(bufferingSettings);
+ invokeConnectAsync();
+ std::unique_lock waitForDownloadComplete(mDownloadCompleteMutex);
+ mConditionalVariable.wait(waitForDownloadComplete,
+ [this] { return mEosReached; });
+ if (mLiveSession->isSeekable()) {
+ invokeSeekTo();
+ }
+ invokeDequeueAccessUnit();
+ size_t index = mFDP->ConsumeIntegral<size_t>();
+ bool select = mFDP->ConsumeBool();
+ mLiveSession->selectTrack(index, select);
+ mLiveSession->hasDynamicDuration();
+ int64_t firstTimeUs =
+ mFDP->ConsumeIntegralInRange<int64_t>(kRangeMin, kRangeMax);
+ int64_t timeUs = mFDP->ConsumeIntegralInRange<int64_t>(kRangeMin, kRangeMax);
+ int32_t discontinuitySeq = mFDP->ConsumeIntegral<int32_t>();
+ mLiveSession->calculateMediaTimeUs(firstTimeUs, timeUs, discontinuitySeq);
+ invokeGetConfig();
+}
+
+void HttpLiveFuzzer::process(const uint8_t *data, size_t size) {
+ mFDP = new FuzzedDataProvider(data, size);
+ createM3U8File(data, size);
+ invokeLiveDataSource();
+ invokeLiveSession();
+ delete mFDP;
+}
+
+void HttpLiveFuzzer::deInitLiveSession() {
+ if (mLiveSession != nullptr) {
+ mLiveSession->disconnect();
+ mLiveLooper->unregisterHandler(mLiveSession->id());
+ mLiveLooper->stop();
+ }
+ mLiveSession.clear();
+ mLiveLooper.clear();
+}
+
+void HttpLiveFuzzer::signalEos() {
+ mEosReached = true;
+ {
+ std::lock_guard<std::mutex> waitForDownloadComplete(mDownloadCompleteMutex);
+ }
+ mConditionalVariable.notify_one();
+ return;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ HttpLiveFuzzer httpliveFuzzer;
+ httpliveFuzzer.process(data, size);
+ return 0;
+}
diff --git a/media/libstagefright/httplive/fuzzer/httplive_fuzzer.dict b/media/libstagefright/httplive/fuzzer/httplive_fuzzer.dict
new file mode 100644
index 0000000..703cc7e
--- /dev/null
+++ b/media/libstagefright/httplive/fuzzer/httplive_fuzzer.dict
@@ -0,0 +1,15 @@
+#m3u8-Tags
+kw1="#EXTM3U"
+kw2="#EXT-X-VERSION:"
+kw3="#EXT-X-TARGETDURATION:"
+kw4="#EXT-X-PLAYLIST-TYPE:"
+kw5="#EXTINF:"
+kw6="#EXT-X-ENDLIST"
+kw7="#EXT-X-MEDIA-SEQUENCE:"
+kw8="#EXT-X-KEY:METHOD=NONE"
+kw9="#EXT-X-DISCONTINUITY:"
+kw10="#EXT-X-DISCONTINUITY-SEQUENCE:0"
+kw11="#EXT-X-STREAM-INF:BANDWIDTH="
+kw12="#EXT-X-STREAM-INF:CODECS="
+kw13="#EXT-X-BYTERANGE:"
+kw14="#EXT-X-MEDIA"
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index c84cc10..632b32c 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -71,6 +71,9 @@
virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface);
virtual void initiateStart();
virtual void initiateShutdown(bool keepComponentAllocated = false);
+ virtual status_t querySupportedParameters(std::vector<std::string> *names) override;
+ virtual status_t subscribeToParameters(const std::vector<std::string> &names) override;
+ virtual status_t unsubscribeFromParameters(const std::vector<std::string> &names) override;
status_t queryCapabilities(
const char* owner, const char* name,
diff --git a/media/libstagefright/include/media/stagefright/MediaBuffer.h b/media/libstagefright/include/media/stagefright/MediaBuffer.h
index 2c03f27..f070aac 100644
--- a/media/libstagefright/include/media/stagefright/MediaBuffer.h
+++ b/media/libstagefright/include/media/stagefright/MediaBuffer.h
@@ -105,7 +105,6 @@
if (mMemory.get() == nullptr || mMemory->unsecurePointer() == nullptr) return 0;
int32_t remoteRefcount =
reinterpret_cast<SharedControl *>(mMemory->unsecurePointer())->getRemoteRefcount();
- // Sanity check so that remoteRefCount() is non-negative.
return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data.
#else
return 0;
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index 4237e8c..3a01925 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -364,7 +364,7 @@
inline static const char *asString_AV1Profile(int32_t i, const char *def = "??") {
switch (i) {
case AV1ProfileMain8: return "Main8";
- case AV1ProfileMain10: return "Main10HDR";
+ case AV1ProfileMain10: return "Main10";
case AV1ProfileMain10HDR10: return "Main10HDR10";
case AV1ProfileMain10HDR10Plus: return "Main10HDRPlus";
default: return def;
diff --git a/media/libstagefright/tests/fuzzers/Android.bp b/media/libstagefright/tests/fuzzers/Android.bp
index 0097830..ea17a4d 100644
--- a/media/libstagefright/tests/fuzzers/Android.bp
+++ b/media/libstagefright/tests/fuzzers/Android.bp
@@ -86,9 +86,6 @@
dictionary: "dictionaries/formats.dict",
defaults: ["libstagefright_fuzzer_defaults"],
static_libs: [
- "libstagefright_webm",
"libdatasource",
- "libstagefright_esds",
- "libogg",
],
}
diff --git a/media/mtp/OWNERS b/media/mtp/OWNERS
index 1928ba8..54d3d4a 100644
--- a/media/mtp/OWNERS
+++ b/media/mtp/OWNERS
@@ -1,6 +1,5 @@
set noparent
-marcone@google.com
jsharkey@android.com
jameswei@google.com
rmojumder@google.com
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index 1ae2b44..0e2de4e 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -452,17 +452,19 @@
uint32_t flags) {
sp<AMessage> nativeFormat;
AMediaFormat_getFormat(format, &nativeFormat);
- ALOGV("configure with format: %s", nativeFormat->debugString(0).c_str());
+ // create our shallow copy, so we aren't victim to any later changes.
+ sp<AMessage> dupNativeFormat = nativeFormat->dup();
+ ALOGV("configure with format: %s", dupNativeFormat->debugString(0).c_str());
sp<Surface> surface = NULL;
if (window != NULL) {
surface = (Surface*) window;
}
- status_t err = mData->mCodec->configure(nativeFormat, surface,
+ status_t err = mData->mCodec->configure(dupNativeFormat, surface,
crypto ? crypto->mCrypto : NULL, flags);
if (err != OK) {
ALOGE("configure: err(%d), failed with format: %s",
- err, nativeFormat->debugString(0).c_str());
+ err, dupNativeFormat->debugString(0).c_str());
}
return translate_error(err);
}
diff --git a/media/ndk/OWNERS b/media/ndk/OWNERS
index 9dc441e..83644f0 100644
--- a/media/ndk/OWNERS
+++ b/media/ndk/OWNERS
@@ -1,3 +1,4 @@
-marcone@google.com
+essick@google.com
+lajos@google.com
# For AImage/AImageReader
include platform/frameworks/av:/camera/OWNERS
diff --git a/media/tests/SampleVideoEncoder/app/src/main/AndroidManifest.xml b/media/tests/SampleVideoEncoder/app/src/main/AndroidManifest.xml
index b17541d..75d73bf 100644
--- a/media/tests/SampleVideoEncoder/app/src/main/AndroidManifest.xml
+++ b/media/tests/SampleVideoEncoder/app/src/main/AndroidManifest.xml
@@ -30,7 +30,8 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
- <activity android:name="com.android.media.samplevideoencoder.MainActivity">
+ <activity android:name="com.android.media.samplevideoencoder.MainActivity"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -42,4 +43,4 @@
android:targetPackage="com.android.media.samplevideoencoder"
android:label="SampleVideoEncoder Test"/>
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/media/tests/benchmark/MediaBenchmarkTest/Android.bp b/media/tests/benchmark/MediaBenchmarkTest/Android.bp
index 2e06da5..4b44dcf 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/Android.bp
+++ b/media/tests/benchmark/MediaBenchmarkTest/Android.bp
@@ -69,7 +69,6 @@
java_defaults {
name: "MediaBenchmark-defaults",
- sdk_version: "system_current",
min_sdk_version: "28",
- target_sdk_version: "29",
+ target_sdk_version: "30",
}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/build.gradle b/media/tests/benchmark/MediaBenchmarkTest/build.gradle
index b2aee1a..b222d47 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/build.gradle
+++ b/media/tests/benchmark/MediaBenchmarkTest/build.gradle
@@ -17,21 +17,21 @@
buildscript {
repositories {
google()
- jcenter()
+ mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.0'
+ classpath 'com.android.tools.build:gradle:4.2.1'
}
}
apply plugin: 'com.android.application'
android {
- compileSdkVersion 29
+ compileSdkVersion 30
defaultConfig {
applicationId "com.android.media.benchmark"
minSdkVersion 28
- targetSdkVersion 29
+ targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -57,20 +57,20 @@
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
- version "3.10.2"
+ version "3.18.1"
}
}
}
repositories {
google()
- jcenter()
+ mavenCentral()
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.1.0'
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'androidx.test:runner:1.2.0'
- androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+ implementation 'androidx.appcompat:appcompat:1.3.0'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test:runner:1.3.0'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.2'
}
\ No newline at end of file
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/Android.bp b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/Android.bp
index af92424..0192d68 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/Android.bp
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/Android.bp
@@ -9,7 +9,6 @@
cc_test_library {
name: "libmediabenchmark_jni",
- sdk_version: "current",
defaults: [
"libmediabenchmark_common-defaults",
diff --git a/media/tests/benchmark/src/native/common/Android.bp b/media/tests/benchmark/src/native/common/Android.bp
index 6b54c6a..718d217 100644
--- a/media/tests/benchmark/src/native/common/Android.bp
+++ b/media/tests/benchmark/src/native/common/Android.bp
@@ -55,7 +55,6 @@
cc_defaults {
name: "libmediabenchmark-defaults",
- sdk_version: "current",
stl: "c++_shared",
shared_libs: [
diff --git a/media/tests/benchmark/src/native/extractor/Extractor.cpp b/media/tests/benchmark/src/native/extractor/Extractor.cpp
index f0bb3b9..3bdfbad 100644
--- a/media/tests/benchmark/src/native/extractor/Extractor.cpp
+++ b/media/tests/benchmark/src/native/extractor/Extractor.cpp
@@ -124,9 +124,7 @@
int64_t sTime = mStats->getCurTime();
if (mExtractor) {
- // TODO: (b/140128505) Multiple calls result in DoS.
- // Uncomment call to AMediaExtractor_delete() once this is resolved
- // AMediaExtractor_delete(mExtractor);
+ AMediaExtractor_delete(mExtractor);
mExtractor = nullptr;
}
int64_t eTime = mStats->getCurTime();
diff --git a/media/tests/benchmark/tests/Android.bp b/media/tests/benchmark/tests/Android.bp
index 0fbd20d..9a8caa3 100644
--- a/media/tests/benchmark/tests/Android.bp
+++ b/media/tests/benchmark/tests/Android.bp
@@ -33,7 +33,12 @@
srcs: ["ExtractorTest.cpp"],
- static_libs: ["libmediabenchmark_extractor"]
+ static_libs: ["libmediabenchmark_extractor"],
+
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ ],
}
cc_test {
@@ -50,6 +55,11 @@
"libmediabenchmark_extractor",
"libmediabenchmark_decoder",
],
+
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ ],
}
cc_test {
diff --git a/media/tests/benchmark/tests/DecoderTest.cpp b/media/tests/benchmark/tests/DecoderTest.cpp
index 81ef02a..3666724 100644
--- a/media/tests/benchmark/tests/DecoderTest.cpp
+++ b/media/tests/benchmark/tests/DecoderTest.cpp
@@ -21,6 +21,8 @@
#include <iostream>
#include <limits>
+#include <android/binder_process.h>
+
#include "BenchmarkTestEnvironment.h"
#include "Decoder.h"
@@ -175,6 +177,7 @@
"c2.android.hevc.decoder", true)));
int main(int argc, char **argv) {
+ ABinderProcess_startThreadPool();
gEnv = new BenchmarkTestEnvironment();
::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
diff --git a/media/tests/benchmark/tests/ExtractorTest.cpp b/media/tests/benchmark/tests/ExtractorTest.cpp
index d14d15b..27ee9ba 100644
--- a/media/tests/benchmark/tests/ExtractorTest.cpp
+++ b/media/tests/benchmark/tests/ExtractorTest.cpp
@@ -19,6 +19,8 @@
#include <gtest/gtest.h>
+#include <android/binder_process.h>
+
#include "BenchmarkTestEnvironment.h"
#include "Extractor.h"
@@ -73,6 +75,7 @@
0)));
int main(int argc, char **argv) {
+ ABinderProcess_startThreadPool();
gEnv = new BenchmarkTestEnvironment();
::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index bfe73d5..e3b837e 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -51,6 +51,7 @@
"libpermission",
"android.hardware.graphics.bufferqueue@1.0",
"android.hidl.token@1.0-utils",
+ "packagemanager_aidl-cpp",
],
export_static_lib_headers: [
"libbatterystats_aidl",
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 9c7b863..42f48a5 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -101,7 +101,11 @@
AttributionSourceState myAttributionSource;
myAttributionSource.uid = VALUE_OR_FATAL(android::legacy2aidl_uid_t_int32_t(getuid()));
myAttributionSource.pid = VALUE_OR_FATAL(android::legacy2aidl_pid_t_int32_t(getpid()));
- myAttributionSource.token = sp<BBinder>::make();
+ if (callerAttributionSource.token != nullptr) {
+ myAttributionSource.token = callerAttributionSource.token;
+ } else {
+ myAttributionSource.token = sp<BBinder>::make();
+ }
myAttributionSource.next.push_back(nextAttributionSource);
return std::optional<AttributionSourceState>{myAttributionSource};
diff --git a/media/utils/fuzzers/Android.bp b/media/utils/fuzzers/Android.bp
index c1698dc..c4dc24f 100644
--- a/media/utils/fuzzers/Android.bp
+++ b/media/utils/fuzzers/Android.bp
@@ -18,6 +18,7 @@
"libutils",
"libbinder",
"framework-permission-aidl-cpp",
+ "packagemanager_aidl-cpp",
],
cflags: [
diff --git a/services/OWNERS b/services/OWNERS
index f0b5e2f..17e605d 100644
--- a/services/OWNERS
+++ b/services/OWNERS
@@ -1,9 +1,6 @@
-chz@google.com
elaurent@google.com
essick@google.com
etalvala@google.com
-gkasten@google.com
hunga@google.com
-marcone@google.com
nchalko@google.com
quxiangfang@google.com
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index b91f302..fecc183 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -81,6 +81,7 @@
"libmedia_helper",
"libshmemcompat",
"libvibrator",
+ "packagemanager_aidl-cpp",
],
static_libs: [
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 65a163f..6cdb3cd 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -997,8 +997,9 @@
}
}
}
-
- setAudioHwSyncForSession_l(thread, sessionId);
+ if ((output.flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) == AUDIO_OUTPUT_FLAG_HW_AV_SYNC) {
+ setAudioHwSyncForSession_l(thread, sessionId);
+ }
}
if (lStatus != NO_ERROR) {
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index a381c7d..b82601a 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -573,6 +573,12 @@
// create a special playback track to render to playback thread.
// this track is given the same buffer as the PatchRecord buffer
+
+ // Default behaviour is to start as soon as possible to have the lowest possible latency even if
+ // it might glitch.
+ // Disable this behavior for FM Tuner source if no fast capture/mixer available.
+ const bool isFmBridge = mAudioPatch.sources[0].ext.device.type == AUDIO_DEVICE_IN_FM_TUNER;
+ const size_t frameCountToBeReady = isFmBridge && !usePassthruPatchRecord ? frameCount / 4 : 1;
sp<PlaybackThread::PatchTrack> tempPatchTrack = new PlaybackThread::PatchTrack(
mPlayback.thread().get(),
streamType,
@@ -582,7 +588,9 @@
frameCount,
tempRecordTrack->buffer(),
tempRecordTrack->bufferSize(),
- outputFlags);
+ outputFlags,
+ {} /*timeout*/,
+ frameCountToBeReady);
status = mPlayback.checkTrack(tempPatchTrack.get());
if (status != NO_ERROR) {
return status;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 0929055..04b1c6d 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -183,6 +183,12 @@
}
}
+ static bool checkServerLatencySupported(
+ audio_format_t format, audio_output_flags_t flags) {
+ return audio_is_linear_pcm(format)
+ && (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) == 0;
+ }
+
audio_output_flags_t getOutputFlags() const { return mFlags; }
float getSpeed() const { return mSpeed; }
protected:
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index e0c5fa5..233865f 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -713,8 +713,7 @@
thread->mFastTrackAvailMask &= ~(1 << i);
}
- mServerLatencySupported = thread->type() == ThreadBase::MIXER
- || thread->type() == ThreadBase::DUPLICATING;
+ mServerLatencySupported = checkServerLatencySupported(format, flags);
#ifdef TEE_SINK
mTee.setId(std::string("_") + std::to_string(mThreadIoHandle)
+ "_" + std::to_string(mId) + "_T");
@@ -1405,6 +1404,60 @@
.content_type = mAttr.content_type,
.gain = mFinalVolume,
};
+
+ // When attributes are undefined, derive default values from stream type.
+ // See AudioAttributes.java, usageForStreamType() and Builder.setInternalLegacyStreamType()
+ if (mAttr.usage == AUDIO_USAGE_UNKNOWN) {
+ switch (mStreamType) {
+ case AUDIO_STREAM_VOICE_CALL:
+ metadata.base.usage = AUDIO_USAGE_VOICE_COMMUNICATION;
+ metadata.base.content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ break;
+ case AUDIO_STREAM_SYSTEM:
+ metadata.base.usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+ metadata.base.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ break;
+ case AUDIO_STREAM_RING:
+ metadata.base.usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+ metadata.base.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ break;
+ case AUDIO_STREAM_MUSIC:
+ metadata.base.usage = AUDIO_USAGE_MEDIA;
+ metadata.base.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ break;
+ case AUDIO_STREAM_ALARM:
+ metadata.base.usage = AUDIO_USAGE_ALARM;
+ metadata.base.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ break;
+ case AUDIO_STREAM_NOTIFICATION:
+ metadata.base.usage = AUDIO_USAGE_NOTIFICATION;
+ metadata.base.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ break;
+ case AUDIO_STREAM_DTMF:
+ metadata.base.usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+ metadata.base.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ break;
+ case AUDIO_STREAM_ACCESSIBILITY:
+ metadata.base.usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+ metadata.base.content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ break;
+ case AUDIO_STREAM_ASSISTANT:
+ metadata.base.usage = AUDIO_USAGE_ASSISTANT;
+ metadata.base.content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ break;
+ case AUDIO_STREAM_REROUTING:
+ metadata.base.usage = AUDIO_USAGE_VIRTUAL_SOURCE;
+ // unknown content type
+ break;
+ case AUDIO_STREAM_CALL_ASSISTANT:
+ metadata.base.usage = AUDIO_USAGE_CALL_ASSISTANT;
+ metadata.base.content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ break;
+ default:
+ break;
+ }
+ }
+
metadata.channel_mask = mChannelMask,
strncpy(metadata.tags, mAttr.tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
*backInserter++ = metadata;
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 2e49e71..602671e 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -285,8 +285,8 @@
virtual bool isHapticPlaybackSupported() = 0;
- virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
- std::vector<audio_format_t> *formats) = 0;
+ virtual status_t getHwOffloadFormatsSupportedForBluetoothMedia(
+ audio_devices_t device, std::vector<audio_format_t> *formats) = 0;
virtual void setAppState(audio_port_handle_t portId, app_state_t state) = 0;
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index 9ba745a..54b3408 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -80,6 +80,7 @@
sp<DeviceDescriptor> getRouteSinkDevice(const sp<AudioRoute> &route) const;
DeviceVector getRouteSourceDevices(const sp<AudioRoute> &route) const;
+ const AudioRouteVector& getRoutes() const { return mRoutes; }
void setRoutes(const AudioRouteVector &routes);
status_t addOutputProfile(const sp<IOProfile> &profile);
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index a92d31e..561fab3 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -58,15 +58,6 @@
mDeclaredAddress(DeviceDescriptorBase::address())
{
mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
- /* If framework runs against a pre 5.0 Audio HAL, encoded formats are absent from the config.
- * FIXME: APM should know the version of the HAL and don't add the formats for V5.0.
- * For now, the workaround to remove AC3 and IEC61937 support on HDMI is to declare
- * something like 'encodedFormats="AUDIO_FORMAT_PCM_16_BIT"' on the HDMI devicePort.
- */
- if (mDeviceTypeAddr.mType == AUDIO_DEVICE_OUT_HDMI && mEncodedFormats.empty()) {
- mEncodedFormats.push_back(AUDIO_FORMAT_AC3);
- mEncodedFormats.push_back(AUDIO_FORMAT_IEC61937);
- }
}
void DeviceDescriptor::attach(const sp<HwModule>& module)
diff --git a/services/audiopolicy/common/managerdefinitions/src/PolicyAudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/PolicyAudioPort.cpp
index 8c61b90..5986069 100644
--- a/services/audiopolicy/common/managerdefinitions/src/PolicyAudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/PolicyAudioPort.cpp
@@ -30,9 +30,9 @@
// --- PolicyAudioPort class implementation
void PolicyAudioPort::attach(const sp<HwModule>& module)
{
+ mModule = module;
ALOGV("%s: attaching module %s to port %s",
__FUNCTION__, getModuleName(), asAudioPort()->getName().c_str());
- mModule = module;
}
void PolicyAudioPort::detach()
diff --git a/services/audiopolicy/config/bluetooth_audio_policy_configuration.xml b/services/audiopolicy/config/bluetooth_audio_policy_configuration.xml
index 98415b7..22ff954 100644
--- a/services/audiopolicy/config/bluetooth_audio_policy_configuration.xml
+++ b/services/audiopolicy/config/bluetooth_audio_policy_configuration.xml
@@ -22,6 +22,17 @@
samplingRates="8000,16000,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
+ <mixPort name="le audio input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
+ samplingRates="8000,16000,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+ samplingRates="8000,16000,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </mixPort>
</mixPorts>
<devicePorts>
<!-- A2DP Audio Ports -->
@@ -49,6 +60,7 @@
-->
<devicePort tagName="BLE Headset Out" type="AUDIO_DEVICE_OUT_BLE_HEADSET" role="sink"/>
<devicePort tagName="BLE Speaker Out" type="AUDIO_DEVICE_OUT_BLE_SPEAKER" role="sink"/>
+ <devicePort tagName="BLE Headset In" type="AUDIO_DEVICE_IN_BLE_HEADSET" role="source"/>
</devicePorts>
<routes>
<route type="mix" sink="BT A2DP Out"
@@ -61,6 +73,8 @@
sources="hearing aid output"/>
<route type="mix" sink="BLE Headset Out"
sources="le audio output"/>
+ <route type="mix" sink="le audio input"
+ sources="BLE Headset In"/>
<route type="mix" sink="BLE Speaker Out"
sources="le audio output"/>
</routes>
diff --git a/services/audiopolicy/config/bluetooth_audio_policy_configuration_7_0.xml b/services/audiopolicy/config/bluetooth_audio_policy_configuration_7_0.xml
index fbe7571..aad00d6 100644
--- a/services/audiopolicy/config/bluetooth_audio_policy_configuration_7_0.xml
+++ b/services/audiopolicy/config/bluetooth_audio_policy_configuration_7_0.xml
@@ -22,6 +22,17 @@
samplingRates="8000 16000 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
+ <mixPort name="le audio input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
+ samplingRates="8000 16000 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+ samplingRates="8000 16000 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+ </mixPort>
</mixPorts>
<devicePorts>
<!-- A2DP Audio Ports -->
@@ -45,6 +56,7 @@
<!-- BLE Audio Ports -->
<devicePort tagName="BLE Headset Out" type="AUDIO_DEVICE_OUT_BLE_HEADSET" role="sink"/>
<devicePort tagName="BLE Speaker Out" type="AUDIO_DEVICE_OUT_BLE_SPEAKER" role="sink"/>
+ <devicePort tagName="BLE Headset In" type="AUDIO_DEVICE_IN_BLE_HEADSET" role="source"/>
</devicePorts>
<routes>
<route type="mix" sink="BT A2DP Out"
@@ -57,6 +69,8 @@
sources="hearing aid output"/>
<route type="mix" sink="BLE Headset Out"
sources="le audio output"/>
+ <route type="mix" sink="le audio input"
+ sources="BLE Headset In"/>
<route type="mix" sink="BLE Speaker Out"
sources="le audio output"/>
</routes>
diff --git a/services/audiopolicy/config/le_audio_policy_configuration.xml b/services/audiopolicy/config/le_audio_policy_configuration.xml
index a3dc72b..dcdd805 100644
--- a/services/audiopolicy/config/le_audio_policy_configuration.xml
+++ b/services/audiopolicy/config/le_audio_policy_configuration.xml
@@ -7,13 +7,20 @@
samplingRates="8000,16000,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
+ <mixPort name="le audio input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT,AUDIO_FORMAT_PCM_24_BIT,AUDIO_FORMAT_PCM_32_BIT"
+ samplingRates="8000,16000,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </mixPort>
</mixPorts>
<devicePorts>
<devicePort tagName="BLE Headset Out" type="AUDIO_DEVICE_OUT_BLE_HEADSET" role="sink"/>
<devicePort tagName="BLE Speaker Out" type="AUDIO_DEVICE_OUT_BLE_SPEAKER" role="sink"/>
+ <devicePort tagName="BLE Headset In" type="AUDIO_DEVICE_IN_BLE_HEADSET" role="source"/>
</devicePorts>
<routes>
<route type="mix" sink="BLE Headset Out" sources="le audio output"/>
<route type="mix" sink="BLE Speaker Out" sources="le audio output"/>
+ <route type="mix" sink="le audio input" sources="BLE Headset In"/>
</routes>
</module>
diff --git a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
index d39eff6..665c2dd 100644
--- a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
+++ b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
@@ -69,12 +69,6 @@
{
{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_NONE, ""},
- {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""},
- {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""},
- {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""},
{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_NOTIFICATION_EVENT,
AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""}
}
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
index bc32416..0ddf66d 100644
--- a/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -57,9 +57,6 @@
<ProductStrategy name="STRATEGY_SONIFICATION_RESPECTFUL">
<AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION" volumeGroup="notification">
<Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
- <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
- <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
- <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
<Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
</AttributesGroup>
</ProductStrategy>
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index b0c376a..9a61a05 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -299,8 +299,13 @@
if (device != nullptr) {
return DeviceVector(device);
}
+ return fromCache? getCachedDevices(strategy) : getDevicesForProductStrategy(strategy);
+}
- return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
+DeviceVector Engine::getCachedDevices(product_strategy_t ps) const
+{
+ return mDevicesForStrategies.find(ps) != mDevicesForStrategies.end() ?
+ mDevicesForStrategies.at(ps) : DeviceVector{};
}
DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index d8e2742..f665da5 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -126,6 +126,7 @@
status_t loadAudioPolicyEngineConfig();
DeviceVector getDevicesForProductStrategy(product_strategy_t strategy) const;
+ DeviceVector getCachedDevices(product_strategy_t ps) const;
/**
* Policy Parameter Manager hidden through a wrapper.
diff --git a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
index bc32416..0ddf66d 100644
--- a/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
+++ b/services/audiopolicy/enginedefault/config/example/phone/audio_policy_engine_product_strategies.xml
@@ -57,9 +57,6 @@
<ProductStrategy name="STRATEGY_SONIFICATION_RESPECTFUL">
<AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION" volumeGroup="notification">
<Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
- <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
- <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
- <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
<Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
</AttributesGroup>
</ProductStrategy>
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index cb9d700..4ce7851 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -525,10 +525,10 @@
return NO_ERROR;
}
-status_t AudioPolicyManager::getHwOffloadEncodingFormatsSupportedForA2DP(
- std::vector<audio_format_t> *formats)
+status_t AudioPolicyManager::getHwOffloadFormatsSupportedForBluetoothMedia(
+ audio_devices_t device, std::vector<audio_format_t> *formats)
{
- ALOGV("getHwOffloadEncodingFormatsSupportedForA2DP()");
+ ALOGV("getHwOffloadFormatsSupportedForBluetoothMedia()");
status_t status = NO_ERROR;
std::unordered_set<audio_format_t> formatSet;
sp<HwModule> primaryModule =
@@ -537,8 +537,23 @@
ALOGE("%s() unable to get primary module", __func__);
return NO_INIT;
}
+
+ DeviceTypeSet audioDeviceSet;
+
+ switch(device) {
+ case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
+ audioDeviceSet = getAudioDeviceOutAllA2dpSet();
+ break;
+ case AUDIO_DEVICE_OUT_BLE_HEADSET:
+ audioDeviceSet = getAudioDeviceOutAllBleSet();
+ break;
+ default:
+ ALOGE("%s() device type 0x%08x not supported", __func__, device);
+ return BAD_VALUE;
+ }
+
DeviceVector declaredDevices = primaryModule->getDeclaredDevices().getDevicesFromTypes(
- getAudioDeviceOutAllA2dpSet());
+ audioDeviceSet);
for (const auto& device : declaredDevices) {
formatSet.insert(device->encodedFormats().begin(), device->encodedFormats().end());
}
@@ -2147,7 +2162,7 @@
}
// Explicit routing?
- sp<DeviceDescriptor> explicitRoutingDevice =
+ sp<DeviceDescriptor> explicitRoutingDevice =
mAvailableInputDevices.getDeviceFromId(*selectedDeviceId);
// special case for mmap capture: if an input IO handle is specified, we reuse this input if
@@ -2333,7 +2348,7 @@
profileFlags = AUDIO_INPUT_FLAG_NONE; // retry
} else { // fail
ALOGW("%s could not find profile for device %s, sampling rate %u, format %#x, "
- "channel mask 0x%X, flags %#x", __func__, device->toString().c_str(),
+ "channel mask 0x%X, flags %#x", __func__, device->toString().c_str(),
config->sample_rate, config->format, config->channel_mask, flags);
return input;
}
@@ -4953,9 +4968,8 @@
continue;
}
mHwModules.push_back(hwModule);
- // open all output streams needed to access attached devices
- // except for direct output streams that are only opened when they are actually
- // required by an app.
+ // open all output streams needed to access attached devices.
+ // direct outputs are closed immediately after checking the availability of attached devices
// This also validates mAvailableOutputDevices list
for (const auto& outProfile : hwModule->getOutputProfiles()) {
if (!outProfile->canOpenNewIo()) {
@@ -5351,7 +5365,7 @@
} // endif input != 0
if (input == AUDIO_IO_HANDLE_NONE) {
- ALOGW("%s could not open input for device %s", __func__,
+ ALOGW("%s could not open input for device %s", __func__,
device->toString().c_str());
profiles.removeAt(profile_index);
profile_index--;
@@ -5843,7 +5857,8 @@
return hasVoiceStream(streams) && (outputDesc == mPrimaryOutput ||
outputDesc->isActive(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) &&
(isInCall() ||
- mOutputs.isStrategyActiveOnSameModule(productStrategy, outputDesc));
+ mOutputs.isStrategyActiveOnSameModule(productStrategy, outputDesc)) &&
+ !isStreamActive(AUDIO_STREAM_ENFORCED_AUDIBLE, 0);
};
// With low-latency playing on speaker, music on WFD, when the first low-latency
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 98f96d1..c4885e4 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -320,8 +320,8 @@
audio_format_t *surroundFormats);
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
- virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
- std::vector<audio_format_t> *formats);
+ virtual status_t getHwOffloadFormatsSupportedForBluetoothMedia(
+ audio_devices_t device, std::vector<audio_format_t> *formats);
virtual void setAppState(audio_port_handle_t portId, app_state_t state);
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index 454c020..d504659 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -47,6 +47,7 @@
"audiopolicy-types-aidl-cpp",
"capture_state_listener-aidl-cpp",
"framework-permission-aidl-cpp",
+ "packagemanager_aidl-cpp",
],
static_libs: [
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 77223b6..62dbc8d 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1877,8 +1877,8 @@
return Status::ok();
}
-Status AudioPolicyService::getHwOffloadEncodingFormatsSupportedForA2DP(
- std::vector<media::audio::common::AudioFormat>* _aidl_return) {
+Status AudioPolicyService::getHwOffloadFormatsSupportedForBluetoothMedia(
+ int32_t deviceAidl, std::vector<media::audio::common::AudioFormat>* _aidl_return) {
std::vector<audio_format_t> formats;
if (mAudioPolicyManager == NULL) {
@@ -1886,8 +1886,10 @@
}
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
+ audio_devices_t device = VALUE_OR_RETURN_BINDER_STATUS(
+ aidl2legacy_int32_t_audio_devices_t(deviceAidl));
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
- mAudioPolicyManager->getHwOffloadEncodingFormatsSupportedForA2DP(&formats)));
+ mAudioPolicyManager->getHwOffloadFormatsSupportedForBluetoothMedia(device, &formats)));
*_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(
convertContainer<std::vector<media::audio::common::AudioFormat>>(
formats,
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 4d0e1f1..9190251 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -409,7 +409,7 @@
}
}
-void AudioPolicyService::NotificationClient::onAudioVolumeGroupChanged(volume_group_t group,
+void AudioPolicyService::NotificationClient::onAudioVolumeGroupChanged(volume_group_t group,
int flags)
{
if (mAudioPolicyServiceClient != 0 && mAudioVolumeGroupCallbacksEnabled) {
@@ -970,7 +970,7 @@
case TRANSACTION_removeUidDeviceAffinities:
case TRANSACTION_setUserIdDeviceAffinities:
case TRANSACTION_removeUserIdDeviceAffinities:
- case TRANSACTION_getHwOffloadEncodingFormatsSupportedForA2DP:
+ case TRANSACTION_getHwOffloadFormatsSupportedForBluetoothMedia:
case TRANSACTION_listAudioVolumeGroups:
case TRANSACTION_getVolumeGroupFromAudioAttributes:
case TRANSACTION_acquireSoundTriggerSession:
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 7ed829c..9ec5341 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -194,8 +194,8 @@
std::vector<bool>* formatsEnabled) override;
binder::Status getReportedSurroundFormats(
media::Int* count, std::vector<media::audio::common::AudioFormat>* formats) override;
- binder::Status getHwOffloadEncodingFormatsSupportedForA2DP(
- std::vector<media::audio::common::AudioFormat>* _aidl_return) override;
+ binder::Status getHwOffloadFormatsSupportedForBluetoothMedia(
+ int32_t device, std::vector<media::audio::common::AudioFormat>* _aidl_return) override;
binder::Status setSurroundFormatEnabled(media::audio::common::AudioFormat audioFormat,
bool enabled) override;
binder::Status setAssistantUid(int32_t uid) override;
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index a16ab7d..9d2d2b3 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -1375,7 +1375,8 @@
if (type == AUDIO_DEVICE_OUT_HDMI) {
// Set device connection state failed due to no device descriptor found
// For HDMI case, it is easier to simulate device descriptor not found error
- // by using a undeclared encoded format.
+ // by using an encoded format which isn't listed in the 'encodedFormats'
+ // attribute for this devicePort.
ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address.c_str(), name.c_str(), AUDIO_FORMAT_MAT_2_1));
diff --git a/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml b/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
index 87f0ab9..41ed70c 100644
--- a/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
+++ b/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
@@ -50,7 +50,8 @@
</devicePort>
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
</devicePort>
- <devicePort tagName="Hdmi" type="AUDIO_DEVICE_OUT_HDMI" role="sink">
+ <devicePort tagName="Hdmi" type="AUDIO_DEVICE_OUT_HDMI" role="sink"
+ encodedFormats="AUDIO_FORMAT_AC3">
</devicePort>
<devicePort tagName="Hdmi-In Mic" type="AUDIO_DEVICE_IN_HDMI" role="source">
</devicePort>
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 04b5604..0b6b1fb 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -363,16 +363,18 @@
std::string cameraId(id.c_str());
hardware::camera::common::V1_0::CameraResourceCost cost;
status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
- SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
if (res != OK) {
ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
return;
}
+ SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
res = mCameraProviderManager->getSystemCameraKind(cameraId, &deviceKind);
if (res != OK) {
ALOGE("Failed to query device kind: %s (%d)", strerror(-res), res);
return;
}
+ std::vector<std::string> physicalCameraIds;
+ mCameraProviderManager->isLogicalCamera(cameraId, &physicalCameraIds);
std::set<String8> conflicting;
for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
@@ -381,7 +383,7 @@
{
Mutex::Autolock lock(mCameraStatesLock);
mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
- conflicting, deviceKind));
+ conflicting, deviceKind, physicalCameraIds));
}
if (mFlashlight->hasFlashUnit(id)) {
@@ -560,6 +562,13 @@
onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind);
}
+
+void CameraService::onTorchStatusChanged(const String8& cameraId,
+ TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
+ Mutex::Autolock al(mTorchStatusMutex);
+ onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind);
+}
+
void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
@@ -3683,9 +3692,10 @@
// ----------------------------------------------------------------------------
CameraService::CameraState::CameraState(const String8& id, int cost,
- const std::set<String8>& conflicting, SystemCameraKind systemCameraKind) : mId(id),
+ const std::set<String8>& conflicting, SystemCameraKind systemCameraKind,
+ const std::vector<std::string>& physicalCameras) : mId(id),
mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting),
- mSystemCameraKind(systemCameraKind) {}
+ mSystemCameraKind(systemCameraKind), mPhysicalCameras(physicalCameras) {}
CameraService::CameraState::~CameraState() {}
@@ -3724,6 +3734,11 @@
return mSystemCameraKind;
}
+bool CameraService::CameraState::containsPhysicalCamera(const std::string& physicalCameraId) const {
+ return std::find(mPhysicalCameras.begin(), mPhysicalCameras.end(), physicalCameraId)
+ != mPhysicalCameras.end();
+}
+
bool CameraService::CameraState::addUnavailablePhysicalId(const String8& physicalId) {
Mutex::Autolock lock(mStatusLock);
auto result = mUnavailablePhysicalIds.insert(physicalId);
@@ -4342,18 +4357,9 @@
std::list<String16> retList;
Mutex::Autolock lock(mCameraStatesLock);
for (const auto& state : mCameraStates) {
- std::vector<std::string> physicalCameraIds;
- if (!mCameraProviderManager->isLogicalCamera(state.first.c_str(), &physicalCameraIds)) {
- // This is not a logical multi-camera.
- continue;
+ if (state.second->containsPhysicalCamera(physicalCameraId.c_str())) {
+ retList.emplace_back(String16(state.first));
}
- if (std::find(physicalCameraIds.begin(), physicalCameraIds.end(), physicalCameraId.c_str())
- == physicalCameraIds.end()) {
- // cameraId is not a physical camera of this logical multi-camera.
- continue;
- }
-
- retList.emplace_back(String16(state.first));
}
return retList;
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index bc2e347..d5feeeb 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -110,8 +110,16 @@
virtual void onDeviceStatusChanged(const String8 &cameraId,
const String8 &physicalCameraId,
hardware::camera::common::V1_0::CameraDeviceStatus newHalStatus) override;
+ // This method may hold CameraProviderManager::mInterfaceMutex as a part
+ // of calling getSystemCameraKind() internally. Care should be taken not to
+ // directly / indirectly call this from callers who also hold
+ // mInterfaceMutex.
virtual void onTorchStatusChanged(const String8& cameraId,
hardware::camera::common::V1_0::TorchModeStatus newStatus) override;
+ // Does not hold CameraProviderManager::mInterfaceMutex.
+ virtual void onTorchStatusChanged(const String8& cameraId,
+ hardware::camera::common::V1_0::TorchModeStatus newStatus,
+ SystemCameraKind kind) override;
virtual void onNewProviderRegistered() override;
/////////////////////////////////////////////////////////////////////
@@ -563,7 +571,7 @@
* returned in the HAL's camera_info struct for each device.
*/
CameraState(const String8& id, int cost, const std::set<String8>& conflicting,
- SystemCameraKind deviceKind);
+ SystemCameraKind deviceKind, const std::vector<std::string>& physicalCameras);
virtual ~CameraState();
/**
@@ -621,6 +629,12 @@
SystemCameraKind getSystemCameraKind() const;
/**
+ * Return whether this camera is a logical multi-camera and has a
+ * particular physical sub-camera.
+ */
+ bool containsPhysicalCamera(const std::string& physicalCameraId) const;
+
+ /**
* Add/Remove the unavailable physical camera ID.
*/
bool addUnavailablePhysicalId(const String8& physicalId);
@@ -641,6 +655,7 @@
mutable Mutex mStatusLock;
CameraParameters mShimParams;
const SystemCameraKind mSystemCameraKind;
+ const std::vector<std::string> mPhysicalCameras; // Empty if not a logical multi-camera
}; // class CameraState
// Observer for UID lifecycle enforcing that UIDs in idle
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 4f2b878..0e0f15f 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -1950,16 +1950,19 @@
const hardware::hidl_string& cameraDeviceName,
TorchModeStatus newStatus) {
sp<StatusListener> listener;
+ SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
std::string id;
+ bool known = false;
{
- std::lock_guard<std::mutex> lock(mManager->mStatusListenerMutex);
- bool known = false;
+ // Hold mLock for accessing mDevices
+ std::lock_guard<std::mutex> lock(mLock);
for (auto& deviceInfo : mDevices) {
if (deviceInfo->mName == cameraDeviceName) {
ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
torchStatusToString(newStatus));
id = deviceInfo->mId;
known = true;
+ systemCameraKind = deviceInfo->mSystemCameraKind;
if (TorchModeStatus::AVAILABLE_ON != newStatus) {
mManager->removeRef(DeviceMode::TORCH, id);
}
@@ -1971,11 +1974,19 @@
mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
return hardware::Void();
}
+ // no lock needed since listener is set up only once during
+ // CameraProviderManager initialization and then never changed till it is
+ // destructed.
listener = mManager->getStatusListener();
- }
+ }
// Call without lock held to allow reentrancy into provider manager
+ // The problem with holding mLock here is that we
+ // might be limiting re-entrancy : CameraService::onTorchStatusChanged calls
+ // back into CameraProviderManager which might try to hold mLock again (eg:
+ // findDeviceInfo, which should be holding mLock while iterating through
+ // each provider's devices).
if (listener != nullptr) {
- listener->onTorchStatusChanged(String8(id.c_str()), newStatus);
+ listener->onTorchStatusChanged(String8(id.c_str()), newStatus, systemCameraKind);
}
return hardware::Void();
}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 1bdbb44..baf20c9 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -156,6 +156,9 @@
const String8 &physicalCameraId,
hardware::camera::common::V1_0::CameraDeviceStatus newStatus) = 0;
virtual void onTorchStatusChanged(const String8 &cameraId,
+ hardware::camera::common::V1_0::TorchModeStatus newStatus,
+ SystemCameraKind kind) = 0;
+ virtual void onTorchStatusChanged(const String8 &cameraId,
hardware::camera::common::V1_0::TorchModeStatus newStatus) = 0;
virtual void onNewProviderRegistered() = 0;
};
@@ -336,8 +339,6 @@
// All private members, unless otherwise noted, expect mInterfaceMutex to be locked before use
mutable std::mutex mInterfaceMutex;
- // the status listener update callbacks will lock mStatusMutex
- mutable std::mutex mStatusListenerMutex;
wp<StatusListener> mListener;
ServiceInteractionProxy* mServiceProxy;
diff --git a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
index a74fd9d..c8a6b32 100644
--- a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
@@ -274,6 +274,8 @@
hardware::camera::common::V1_0::CameraDeviceStatus) override {}
void onTorchStatusChanged(const String8 &,
hardware::camera::common::V1_0::TorchModeStatus) override {}
+ void onTorchStatusChanged(const String8 &,
+ hardware::camera::common::V1_0::TorchModeStatus, SystemCameraKind) override {}
void onNewProviderRegistered() override {}
};
diff --git a/services/mediacodec/OWNERS b/services/mediacodec/OWNERS
index c716cce..3453a76 100644
--- a/services/mediacodec/OWNERS
+++ b/services/mediacodec/OWNERS
@@ -1,2 +1,3 @@
jeffv@google.com
-marcone@google.com
+essick@google.com
+wonsik@google.com
diff --git a/services/mediacodec/android.hardware.media.omx@1.0-service.rc b/services/mediacodec/android.hardware.media.omx@1.0-service.rc
index 3ef9a85..845e5cc 100644
--- a/services/mediacodec/android.hardware.media.omx@1.0-service.rc
+++ b/services/mediacodec/android.hardware.media.omx@1.0-service.rc
@@ -3,4 +3,4 @@
user mediacodec
group camera drmrpc mediadrm
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
diff --git a/services/mediacodec/registrant/Android.bp b/services/mediacodec/registrant/Android.bp
index 696b967..d10e339 100644
--- a/services/mediacodec/registrant/Android.bp
+++ b/services/mediacodec/registrant/Android.bp
@@ -7,7 +7,7 @@
default_applicable_licenses: ["frameworks_av_services_mediacodec_license"],
}
-cc_library_shared {
+cc_library {
name: "libmedia_codecserviceregistrant",
vendor_available: true,
srcs: [
diff --git a/services/mediacodec/registrant/fuzzer/Android.bp b/services/mediacodec/registrant/fuzzer/Android.bp
new file mode 100644
index 0000000..43afbf1
--- /dev/null
+++ b/services/mediacodec/registrant/fuzzer/Android.bp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+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_services_mediacodec_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_av_services_mediacodec_license"],
+}
+
+cc_fuzz {
+ name: "codecServiceRegistrant_fuzzer",
+ srcs: [
+ "codecServiceRegistrant_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libmedia_codecserviceregistrant",
+ ],
+ header_libs: [
+ "libmedia_headers",
+ ],
+ defaults: [
+ "libcodec2-hidl-defaults",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ },
+}
diff --git a/services/mediacodec/registrant/fuzzer/README.md b/services/mediacodec/registrant/fuzzer/README.md
new file mode 100644
index 0000000..0ffa063
--- /dev/null
+++ b/services/mediacodec/registrant/fuzzer/README.md
@@ -0,0 +1,56 @@
+# Fuzzer for libmedia_codecserviceregistrant
+
+## Plugin Design Considerations
+The fuzzer plugin for libmedia_codecserviceregistrant is designed based on the understanding of the library and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+libmedia_codecserviceregistrant supports the following parameters:
+1. C2String (parameter name: `c2String`)
+2. Width (parameter name: `width`)
+3. Height (parameter name: `height`)
+4. SamplingRate (parameter name: `samplingRate`)
+5. Channels (parameter name: `channels`)
+6. Stream (parameter name: `stream`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `c2String` |`String` | Value obtained from FuzzedDataProvider|
+| `width` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
+| `height` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
+| `samplingRate` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
+| `channels` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
+| `stream` |`UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the libmedia_codecserviceregistrant module.
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build codecServiceRegistrant_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) codecServiceRegistrant_fuzzer
+```
+#### Steps to run
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/${TARGET_ARCH}/codecServiceRegistrant_fuzzer/codecServiceRegistrant_fuzzer
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/services/mediacodec/registrant/fuzzer/codecServiceRegistrant_fuzzer.cpp b/services/mediacodec/registrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
new file mode 100644
index 0000000..e5983e4
--- /dev/null
+++ b/services/mediacodec/registrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2021 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 "../CodecServiceRegistrant.cpp"
+#include "fuzzer/FuzzedDataProvider.h"
+#include <C2Config.h>
+#include <C2Param.h>
+
+using namespace std;
+
+constexpr char kServiceName[] = "software";
+
+class CodecServiceRegistrantFuzzer {
+public:
+ void process(const uint8_t *data, size_t size);
+ ~CodecServiceRegistrantFuzzer() {
+ delete mH2C2;
+ if (mInputSize) {
+ delete mInputSize;
+ }
+ if (mSampleRateInfo) {
+ delete mSampleRateInfo;
+ }
+ if (mChannelCountInfo) {
+ delete mChannelCountInfo;
+ }
+ }
+
+private:
+ void initH2C2ComponentStore();
+ void invokeH2C2ComponentStore();
+ void invokeConfigSM();
+ void invokeQuerySM();
+ H2C2ComponentStore *mH2C2 = nullptr;
+ C2StreamPictureSizeInfo::input *mInputSize = nullptr;
+ C2StreamSampleRateInfo::output *mSampleRateInfo = nullptr;
+ C2StreamChannelCountInfo::output *mChannelCountInfo = nullptr;
+ C2Param::Index mIndex = C2StreamProfileLevelInfo::output::PARAM_TYPE;
+ C2StreamFrameRateInfo::output mFrameRate;
+ FuzzedDataProvider *mFDP = nullptr;
+};
+
+void CodecServiceRegistrantFuzzer::initH2C2ComponentStore() {
+ using namespace ::android::hardware::media::c2;
+ shared_ptr<C2ComponentStore> store =
+ android::GetCodec2PlatformComponentStore();
+ if (!store) {
+ return;
+ }
+ android::sp<V1_1::IComponentStore> storeV1_1 =
+ new V1_1::utils::ComponentStore(store);
+ if (storeV1_1->registerAsService(string(kServiceName)) != android::OK) {
+ return;
+ }
+ string const preferredStoreName = string(kServiceName);
+ sp<IComponentStore> preferredStore =
+ IComponentStore::getService(preferredStoreName.c_str());
+ mH2C2 = new H2C2ComponentStore(preferredStore);
+}
+
+void CodecServiceRegistrantFuzzer::invokeConfigSM() {
+ vector<C2Param *> configParams;
+ uint32_t width = mFDP->ConsumeIntegral<uint32_t>();
+ uint32_t height = mFDP->ConsumeIntegral<uint32_t>();
+ uint32_t samplingRate = mFDP->ConsumeIntegral<uint32_t>();
+ uint32_t channels = mFDP->ConsumeIntegral<uint32_t>();
+ if (mFDP->ConsumeBool()) {
+ mInputSize = new C2StreamPictureSizeInfo::input(0u, width, height);
+ configParams.push_back(mInputSize);
+ } else {
+ if (mFDP->ConsumeBool()) {
+ mSampleRateInfo = new C2StreamSampleRateInfo::output(0u, samplingRate);
+ configParams.push_back(mSampleRateInfo);
+ }
+ if (mFDP->ConsumeBool()) {
+ mChannelCountInfo = new C2StreamChannelCountInfo::output(0u, channels);
+ configParams.push_back(mChannelCountInfo);
+ }
+ }
+ vector<unique_ptr<C2SettingResult>> failures;
+ mH2C2->config_sm(configParams, &failures);
+}
+
+void CodecServiceRegistrantFuzzer::invokeQuerySM() {
+ vector<C2Param *> stackParams;
+ vector<C2Param::Index> heapParamIndices;
+ if (mFDP->ConsumeBool()) {
+ stackParams = {};
+ heapParamIndices = {};
+ } else {
+ uint32_t stream = mFDP->ConsumeIntegral<uint32_t>();
+ mFrameRate.setStream(stream);
+ stackParams.push_back(&mFrameRate);
+ heapParamIndices.push_back(mIndex);
+ }
+ vector<unique_ptr<C2Param>> heapParams;
+ mH2C2->query_sm(stackParams, heapParamIndices, &heapParams);
+}
+
+void CodecServiceRegistrantFuzzer::invokeH2C2ComponentStore() {
+ initH2C2ComponentStore();
+ shared_ptr<C2Component> component;
+ shared_ptr<C2ComponentInterface> interface;
+ string c2String = mFDP->ConsumeRandomLengthString();
+ mH2C2->createComponent(c2String, &component);
+ mH2C2->createInterface(c2String, &interface);
+ invokeConfigSM();
+ invokeQuerySM();
+
+ vector<shared_ptr<C2ParamDescriptor>> params;
+ mH2C2->querySupportedParams_nb(¶ms);
+
+ C2StoreIonUsageInfo usageInfo;
+ std::vector<C2FieldSupportedValuesQuery> query = {
+ C2FieldSupportedValuesQuery::Possible(
+ C2ParamField::Make(usageInfo, usageInfo.usage)),
+ C2FieldSupportedValuesQuery::Possible(
+ C2ParamField::Make(usageInfo, usageInfo.capacity)),
+ };
+ mH2C2->querySupportedValues_sm(query);
+
+ mH2C2->getName();
+ shared_ptr<C2ParamReflector> paramReflector = mH2C2->getParamReflector();
+ if (paramReflector) {
+ paramReflector->describe(C2ComponentDomainSetting::CORE_INDEX);
+ }
+ mH2C2->listComponents();
+ shared_ptr<C2GraphicBuffer> src;
+ shared_ptr<C2GraphicBuffer> dst;
+ mH2C2->copyBuffer(src, dst);
+}
+
+void CodecServiceRegistrantFuzzer::process(const uint8_t *data, size_t size) {
+ mFDP = new FuzzedDataProvider(data, size);
+ invokeH2C2ComponentStore();
+ /** RegisterCodecServices is called here to improve code coverage */
+ /** as currently it is not called by codecServiceRegistrant */
+ RegisterCodecServices();
+ delete mFDP;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ CodecServiceRegistrantFuzzer codecServiceRegistrantFuzzer;
+ codecServiceRegistrantFuzzer.process(data, size);
+ return 0;
+}
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
index 9058f10..41efce0 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
@@ -84,5 +84,6 @@
getgid32: 1
getegid32: 1
getgroups32: 1
+sysinfo: 1
@include /apex/com.android.media.swcodec/etc/seccomp_policy/code_coverage.arm.policy
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
index 4c51a9c..e151a06 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
@@ -78,5 +78,6 @@
getgid: 1
getegid: 1
getgroups: 1
+sysinfo: 1
@include /apex/com.android.media.swcodec/etc/seccomp_policy/code_coverage.arm64.policy
diff --git a/services/mediaextractor/OWNERS b/services/mediaextractor/OWNERS
index c716cce..2a779c2 100644
--- a/services/mediaextractor/OWNERS
+++ b/services/mediaextractor/OWNERS
@@ -1,2 +1,3 @@
jeffv@google.com
-marcone@google.com
+essick@google.com
+aquilescanta@google.com
diff --git a/services/mediaextractor/mediaextractor.rc b/services/mediaextractor/mediaextractor.rc
index 5fc2941..4fb50d0 100644
--- a/services/mediaextractor/mediaextractor.rc
+++ b/services/mediaextractor/mediaextractor.rc
@@ -3,4 +3,4 @@
user mediaex
group drmrpc mediadrm
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
diff --git a/services/medialog/Android.bp b/services/medialog/Android.bp
index cfc4c40..8088ef0 100644
--- a/services/medialog/Android.bp
+++ b/services/medialog/Android.bp
@@ -26,6 +26,7 @@
"libmediautils",
"libnblog",
"libutils",
+ "packagemanager_aidl-cpp",
],
cflags: [
diff --git a/services/mediametrics/Android.bp b/services/mediametrics/Android.bp
index 5989181..154b4ff 100644
--- a/services/mediametrics/Android.bp
+++ b/services/mediametrics/Android.bp
@@ -114,6 +114,7 @@
"libmediautils",
"libutils",
"mediametricsservice-aidl-cpp",
+ "packagemanager_aidl-cpp",
],
header_libs: [
"libaudioutils_headers",
@@ -171,6 +172,7 @@
"libstatspull",
"libstatssocket",
"libutils",
+ "packagemanager_aidl-cpp",
],
export_shared_lib_headers: [
diff --git a/services/mediametrics/TransactionLog.h b/services/mediametrics/TransactionLog.h
index 0ca4639..fd42518 100644
--- a/services/mediametrics/TransactionLog.h
+++ b/services/mediametrics/TransactionLog.h
@@ -158,7 +158,7 @@
++it) {
if (ll <= 0) break;
if (prefix != nullptr && !startsWith(it->first, prefix)) break;
- auto [s, l] = dumpMapTimeItem(it->second, ll - 1, sinceNs, prefix);
+ std::tie(s, l) = dumpMapTimeItem(it->second, ll - 1, sinceNs, prefix);
if (l == 0) continue; // don't show empty groups (due to sinceNs).
ss << " " << it->first << "\n" << s;
ll -= l + 1;
diff --git a/services/mediametrics/fuzzer/Android.bp b/services/mediametrics/fuzzer/Android.bp
index b03e518..9da7282 100644
--- a/services/mediametrics/fuzzer/Android.bp
+++ b/services/mediametrics/fuzzer/Android.bp
@@ -56,6 +56,7 @@
"libstatssocket",
"libutils",
"mediametricsservice-aidl-cpp",
+ "packagemanager_aidl-cpp",
],
include_dirs: [
diff --git a/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp b/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp
index 8b0b479..06ab16e 100644
--- a/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp
+++ b/services/mediametrics/fuzzer/mediametrics_service_fuzzer.cpp
@@ -48,6 +48,7 @@
void invokeAudioAnalytics(const uint8_t *data, size_t size);
void invokeTimedAction(const uint8_t *data, size_t size);
void process(const uint8_t *data, size_t size);
+ std::atomic_int mValue = 0;
};
void MediaMetricsServiceFuzzer::invokeStartsWith(const uint8_t *data, size_t size) {
@@ -342,11 +343,10 @@
void MediaMetricsServiceFuzzer::invokeTimedAction(const uint8_t *data, size_t size) {
FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
android::mediametrics::TimedAction timedAction;
- std::atomic_int value = 0;
while (fdp.remaining_bytes()) {
timedAction.postIn(std::chrono::seconds(fdp.ConsumeIntegral<int32_t>()),
- [&value] { ++value; });
+ [this] { ++mValue; });
timedAction.size();
}
}
diff --git a/services/mediametrics/tests/Android.bp b/services/mediametrics/tests/Android.bp
index 3baf739..f46fbad 100644
--- a/services/mediametrics/tests/Android.bp
+++ b/services/mediametrics/tests/Android.bp
@@ -33,6 +33,7 @@
"libmediautils",
"libutils",
"mediametricsservice-aidl-cpp",
+ "packagemanager_aidl-cpp",
],
header_libs: [
diff --git a/services/mediaresourcemanager/Android.bp b/services/mediaresourcemanager/Android.bp
index f31202b..5d80744 100644
--- a/services/mediaresourcemanager/Android.bp
+++ b/services/mediaresourcemanager/Android.bp
@@ -90,7 +90,7 @@
],
static_libs: [
- "resourceobserver_aidl_interface-V1-ndk_platform",
+ "resourceobserver_aidl_interface-V1-ndk",
],
include_dirs: ["frameworks/av/include"],
diff --git a/services/mediaresourcemanager/test/Android.bp b/services/mediaresourcemanager/test/Android.bp
index ec4ba58..618626f 100644
--- a/services/mediaresourcemanager/test/Android.bp
+++ b/services/mediaresourcemanager/test/Android.bp
@@ -56,7 +56,7 @@
test_suites: ["device-tests"],
static_libs: [
"libresourcemanagerservice",
- "resourceobserver_aidl_interface-V1-ndk_platform",
+ "resourceobserver_aidl_interface-V1-ndk",
],
shared_libs: [
"libbinder",
diff --git a/services/mediatranscoding/Android.bp b/services/mediatranscoding/Android.bp
index a9fd14f..fa5eb4e 100644
--- a/services/mediatranscoding/Android.bp
+++ b/services/mediatranscoding/Android.bp
@@ -47,7 +47,7 @@
],
static_libs: [
- "mediatranscoding_aidl_interface-ndk_platform",
+ "mediatranscoding_aidl_interface-ndk",
],
cflags: [
@@ -80,7 +80,7 @@
],
static_libs: [
- "mediatranscoding_aidl_interface-ndk_platform",
+ "mediatranscoding_aidl_interface-ndk",
],
cflags: [
diff --git a/services/mediatranscoding/OWNERS b/services/mediatranscoding/OWNERS
index 825c586..9334bfa 100644
--- a/services/mediatranscoding/OWNERS
+++ b/services/mediatranscoding/OWNERS
@@ -1,4 +1,4 @@
-akersten@google.com
-hkuang@google.com
-lnilsson@google.com
+# Bug component: 761430
+# go/android-fwk-media-solutions for info on areas of ownership.
+include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
\ No newline at end of file
diff --git a/services/mediatranscoding/tests/Android.bp b/services/mediatranscoding/tests/Android.bp
index cb180ec..ae13656 100644
--- a/services/mediatranscoding/tests/Android.bp
+++ b/services/mediatranscoding/tests/Android.bp
@@ -34,8 +34,8 @@
],
static_libs: [
- "mediatranscoding_aidl_interface-ndk_platform",
- "resourcemanager_aidl_interface-ndk_platform",
+ "mediatranscoding_aidl_interface-ndk",
+ "resourcemanager_aidl_interface-ndk",
"libmediatranscodingservice",
],
diff --git a/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h b/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
index 0cb2fad..8e17f55 100644
--- a/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
+++ b/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
@@ -259,9 +259,7 @@
static constexpr bool success = true;
static constexpr bool fail = false;
-struct TestClientCallback : public BnTranscodingClientCallback,
- public EventTracker,
- public std::enable_shared_from_this<TestClientCallback> {
+struct TestClientCallback : public BnTranscodingClientCallback, public EventTracker {
TestClientCallback(const char* packageName, int32_t id)
: mClientId(id), mClientPid(PID(id)), mClientUid(UID(id)), mPackageName(packageName) {
ALOGI("TestClientCallback %d created: pid %d, uid %d", id, PID(id), UID(id));
@@ -348,8 +346,8 @@
ALOGD("registering %s with uid %d", packageName, mClientUid);
std::shared_ptr<ITranscodingClient> client;
- Status status =
- service->registerClient(shared_from_this(), kClientName, packageName, &client);
+ Status status = service->registerClient(ref<TestClientCallback>(), kClientName, packageName,
+ &client);
mClient = status.isOk() ? client : nullptr;
return status;
diff --git a/services/minijail/Android.bp b/services/minijail/Android.bp
index 3a89e12..038197f 100644
--- a/services/minijail/Android.bp
+++ b/services/minijail/Android.bp
@@ -31,17 +31,6 @@
export_include_dirs: ["."],
}
-// By adding "vendor_available: true" to "libavservices_minijail", we don't
-// need to have "libavservices_minijail_vendor" any longer.
-// "libavservices_minijail_vendor" will be removed, once we replace it with
-// "libavservices_minijail" in all vendor modules. (b/146313710)
-cc_library_shared {
- name: "libavservices_minijail_vendor",
- vendor: true,
- defaults: ["libavservices_minijail_defaults"],
- export_include_dirs: ["."],
-}
-
// Unit tests.
cc_test {
name: "libavservices_minijail_unittest",
diff --git a/services/minijail/OWNERS b/services/minijail/OWNERS
index 19f4f9f..9ebf41e 100644
--- a/services/minijail/OWNERS
+++ b/services/minijail/OWNERS
@@ -1,2 +1,2 @@
jorgelo@google.com
-marcone@google.com
+essick@google.com
diff --git a/services/oboeservice/Android.bp b/services/oboeservice/Android.bp
index 4c58040..3563d66 100644
--- a/services/oboeservice/Android.bp
+++ b/services/oboeservice/Android.bp
@@ -68,6 +68,7 @@
"aaudio-aidl-cpp",
"framework-permission-aidl-cpp",
"libaudioclient_aidl_conversion",
+ "packagemanager_aidl-cpp",
],
export_shared_lib_headers: [
diff --git a/services/tuner/Android.bp b/services/tuner/Android.bp
index cd11c88..1dcfe53 100644
--- a/services/tuner/Android.bp
+++ b/services/tuner/Android.bp
@@ -89,13 +89,14 @@
"liblog",
"libmedia",
"libutils",
- "tv_tuner_aidl_interface-ndk_platform",
- "tv_tuner_resource_manager_aidl_interface-ndk_platform",
+ "packagemanager_aidl-cpp",
+ "tv_tuner_aidl_interface-ndk",
+ "tv_tuner_resource_manager_aidl_interface-ndk",
"tv_tuner_resource_manager_aidl_interface-cpp",
],
static_libs: [
- "android.hardware.common.fmq-V1-ndk_platform",
+ "android.hardware.common.fmq-V1-ndk",
"libaidlcommonsupport",
],
@@ -128,12 +129,12 @@
"liblog",
"libtunerservice",
"libutils",
- "tv_tuner_resource_manager_aidl_interface-ndk_platform",
+ "tv_tuner_resource_manager_aidl_interface-ndk",
"tv_tuner_resource_manager_aidl_interface-cpp",
],
static_libs: [
- "tv_tuner_aidl_interface-ndk_platform",
+ "tv_tuner_aidl_interface-ndk",
],
init_rc: ["mediatuner.rc"],