media: Use qcom hardware video decoders if opted in
The H.264/AVC and MPEG2 Qualcomm hardware video decoders are currently
not fully compliant with CTS/GTS requirements and therefore disabled by
default. Allow enabling them if requested by conditionally loading a
media codec xml that declares Qualcomm hardware instead of Google
software decoders for those formats.
The new library gets loaded by the Android mediacodec service and
customizes the codec registration.
Issue: FP2P-529
Change-Id: I0f6c080ec6ffd4f4e2d6ed5f2a5ff3aae2e4dd69
diff --git a/media/Android.mk b/media/Android.mk
new file mode 100644
index 0000000..7a16792
--- /dev/null
+++ b/media/Android.mk
@@ -0,0 +1,3 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/media_codecs_8974_hwdec.xml b/media/media_codecs_8974_hwdec.xml
new file mode 100644
index 0000000..262921d
--- /dev/null
+++ b/media/media_codecs_8974_hwdec.xml
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012-2013 The Android Open Source Project
+ Copyright (C) 2014 The Linux Foundation. All rights reserved.
+ Not a contribution.
+ Copyright 2018-2021 Fairphone B.V.
+
+ 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.
+-->
+
+<!--
+8974 Encoder capabilities
+ ______________________________________________________
+ | Codec | W H fps Mbps MB/s |
+ |__________|_________________________________________|
+ | h264 | 3840 2160 30 100 972000 |
+ | | 4096 2160 24 100 829440 |
+ | mpeg4 | 1920 1088 30 40 244800 |
+ | vp8 | 1920 1088 30 20 244800 |
+ | h263 | 864 480 30 2 48600 |
+ |__________|_________________________________________|
+
+ 8974 Decoder capabilities
+ ______________________________________________________
+ | Codec | W H fps Mbps MB/s |
+ |__________|_________________________________________|
+ | h264 | 3840 2160 30 100 972000 |
+ | | 4096 2160 24 100 829440 |
+ | hevc | 1280 720 30 2 108000 |
+ | hevchybd | 1920 1088 30 6 244800 |
+ | mpeg4 | 1920 1088 60 60 489600 |
+ | vc1 | 1920 1088 60 60 489600 |
+ | vp8 | 3820 2160 30 20 972000 |
+ | divx3 | 720 480 30 2 40500 |
+ | div4/5/6 | 1920 1088 30 10 244800 |
+ | h263 | 864 480 30 2 48600 |
+ | mpeg2 | 1920 1088 30 40 244800 |
+ |__________|_________________________________________|
+
+-->
+
+<MediaCodecs>
+ <Include href="media_codecs_google_audio.xml" />
+ <Include href="media_codecs_google_telephony.xml" />
+ <Settings>
+ <Setting name="max-video-encoder-input-buffers" value="9" />
+ </Settings>
+ <Encoders>
+ <!-- Video Hardware -->
+ <MediaCodec name="OMX.qcom.video.encoder.avc" type="video/avc" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="requires-loaded-to-idle-after-allocation" />
+ <Limit name="size" min="96x64" max="4096x2160" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="972000" />
+ <Limit name="bitrate" range="1-100000000" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.encoder.mpeg4" type="video/mp4v-es" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="requires-loaded-to-idle-after-allocation"/>
+ <Limit name="size" min="96x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-40000000" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.encoder.h263" type="video/3gpp" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="requires-loaded-to-idle-after-allocation" />
+ <Limit name="size" min="96x64" max="864x480" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="48600" />
+ <Limit name="bitrate" range="1-2000000" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.encoder.vp8" type="video/x-vnd.on2.vp8" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="requires-loaded-to-idle-after-allocation" />
+ <Limit name="size" min="96x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-20000000" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ </Encoders>
+
+ <Decoders>
+ <!-- Video Hardware -->
+ <MediaCodec name="OMX.qcom.video.decoder.avc" type="video/avc" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="4096x2160" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="972000" />
+ <Limit name="bitrate" range="1-100000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <!-- <MediaCodec name="OMX.qcom.video.decoder.avc.secure" type="video/avc" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="4096x2160" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="972000" />
+ <Limit name="bitrate" range="1-100000000" />
+ <Feature name="adaptive-playback" />
+ <Feature name="secure-playback" required="true" />
+ <Limit name="concurrent-instances" max="4" />
+ </MediaCodec> -->
+ <MediaCodec name="OMX.qcom.video.decoder.mpeg2" type="video/mpeg2" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="96x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-40000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.mpeg2.secure" type="video/mpeg2" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="96x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-40000000" />
+ <Feature name="adaptive-playback" />
+ <Feature name="secure-playback" required="true" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.mpeg4" type="video/mp4v-es" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="489600" />
+ <Limit name="bitrate" range="1-60000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.h263" type="video/3gpp" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="864x480" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="48600" />
+ <Limit name="bitrate" range="1-2000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.vc1" type="video/x-ms-wmv" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="489600" />
+ <Limit name="bitrate" range="1-60000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.divx" type="video/divx" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-10000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.divx311" type="video/divx311" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="720x480" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="40500" />
+ <Limit name="bitrate" range="1-2000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.divx4" type="video/divx4" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-10000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.vp8" type="video/x-vnd.on2.vp8" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="3840x2160" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="972000" />
+ <Limit name="bitrate" range="1-20000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="13" />
+ </MediaCodec>
+ <!-- <MediaCodec name="OMX.qcom.video.decoder.hevc" type="video/hevc" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="1280x720" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="108000" />
+ <Limit name="bitrate" range="1-2000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="3" />
+ </MediaCodec> -->
+ <!-- <MediaCodec name="OMX.qcom.video.decoder.hevchybrid" type="video/hevc" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="64x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-6000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="2" />
+ </MediaCodec> -->
+ </Decoders>
+ <Include href="media_codecs_google_video_8974.xml" />
+</MediaCodecs>
diff --git a/media/registrant/Android.mk b/media/registrant/Android.mk
new file mode 100644
index 0000000..d1af2e2
--- /dev/null
+++ b/media/registrant/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libmedia_codecserviceregistrant
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := CodecServiceRegistrant.cpp
+LOCAL_SHARED_LIBRARIES := \
+ libbase \
+ liblog \
+ libutils \
+ libstagefright_omx \
+ libstagefright_xmlparser \
+ android.hardware.media.omx@1.0
+
+LOCAL_VENDOR_MODULE := true
+LOCAL_CFLAGS := -Wall -Werror
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/registrant/CodecServiceRegistrant.cpp b/media/registrant/CodecServiceRegistrant.cpp
new file mode 100644
index 0000000..705ed33
--- /dev/null
+++ b/media/registrant/CodecServiceRegistrant.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016-2018, The Android Open Source Project
+ * Copyright (c) 2021 Fairphone B.V.
+ *
+ * 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.
+ */
+
+#define LOG_TAG "FP2_CodecServiceRegistrant"
+
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <media/stagefright/omx/1.0/Omx.h>
+#include <media/stagefright/omx/1.0/OmxStore.h>
+
+using namespace android;
+using namespace ::android::hardware::media::omx::V1_0;
+
+static constexpr char const *hwDecProperty = "persist.fp2.use_qcom_hw_vdec";
+static constexpr char const* hwDecMainXmlName = "media_codecs_8974_hwdec.xml";
+
+// Called by frameworks/av/services/mediacodec/main_codecservice.cpp
+extern "C" void RegisterCodecServices() {
+ // Default to software video decoders; only use (legacy) hardware decoders if opted-in.
+ const bool use_qcom_hw_vdec = base::GetBoolProperty(hwDecProperty, false);
+ const char* mainXmlName = use_qcom_hw_vdec
+ ? hwDecMainXmlName
+ : MediaCodecsXmlParser::defaultMainXmlName;
+
+ LOG(INFO) << "FP2: Using Qualcomm hardware video decoders: "
+ << (use_qcom_hw_vdec ? "yes" : "no");
+
+ sp<IOmxStore> omxStore = new implementation::OmxStore(
+ "default", // default parameter value
+ MediaCodecsXmlParser::defaultSearchDirs, // default parameter value
+ mainXmlName);
+
+ // Everything below comes from main_codecservice.cpp
+ if (omxStore == nullptr) {
+ LOG(ERROR) << "Cannot create IOmxStore HAL service.";
+ } else if (omxStore->registerAsService() != OK) {
+ LOG(ERROR) << "Cannot register IOmxStore HAL service.";
+ }
+ sp<IOmx> omx = new implementation::Omx();
+ if (omx == nullptr) {
+ LOG(ERROR) << "Cannot create IOmx HAL service.";
+ } else if (omx->registerAsService() != OK) {
+ LOG(ERROR) << "Cannot register IOmx HAL service.";
+ } else {
+ LOG(INFO) << "IOmx HAL service created.";
+ }
+}
diff --git a/sepolicy/mediacodec.te b/sepolicy/mediacodec.te
new file mode 100644
index 0000000..8e3dc00
--- /dev/null
+++ b/sepolicy/mediacodec.te
@@ -0,0 +1 @@
+get_prop(mediacodec, fp_misc_settings_prop)
diff --git a/sepolicy/property.te b/sepolicy/property.te
index fee9c77..2cc8974 100644
--- a/sepolicy/property.te
+++ b/sepolicy/property.te
@@ -1 +1,2 @@
+type fp_misc_settings_prop, property_type;
type shutdown_reason_prop, property_type;
diff --git a/sepolicy/property_contexts b/sepolicy/property_contexts
index eade775..dc298d0 100644
--- a/sepolicy/property_contexts
+++ b/sepolicy/property_contexts
@@ -1,2 +1,4 @@
+persist.fp2.use_qcom_hw_vdec u:object_r:fp_misc_settings_prop:s0
+
persist.runtime.shutdown_planned u:object_r:shutdown_reason_prop:s0
runtime.last_shutdown_was_clean u:object_r:shutdown_reason_prop:s0
diff --git a/sepolicy/shell.te b/sepolicy/shell.te
new file mode 100644
index 0000000..8257aff
--- /dev/null
+++ b/sepolicy/shell.te
@@ -0,0 +1,2 @@
+# Allow toggling between software/hardware decoders from the shell
+set_prop(shell, fp_misc_settings_prop)
diff --git a/sepolicy/system_app.te b/sepolicy/system_app.te
index 7bd8cff..ac72cd1 100644
--- a/sepolicy/system_app.te
+++ b/sepolicy/system_app.te
@@ -13,6 +13,7 @@
allow system_app sensors_persist_file:dir r_dir_perms;
allow system_app sensors_persist_file:file rw_file_perms;
-# Fairphone misc settings files
+# Fairphone misc settings files and properties
allow system_app fp_misc_settings_file:dir search;
allow system_app fp_misc_settings_file:file rw_file_perms;
+set_prop(system_app, fp_misc_settings_prop)