Merge "CCodec: add more doc to PipelineWatcher"
diff --git a/apex/Android.bp b/apex/Android.bp
index c077a77..9455290 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -12,9 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-apex {
- name: "com.android.media",
- manifest: "manifest.json",
+apex_defaults {
+ name: "com.android.media-defaults",
java_libs: ["updatable-media"],
compile_multilib: "both",
multilib: {
@@ -42,16 +41,29 @@
},
},
key: "com.android.media.key",
+ certificate: ":com.android.media.certificate",
}
apex {
- name: "com.android.media.swcodec",
- manifest: "manifest_codec.json",
+ name: "com.android.media",
+ manifest: "manifest.json",
+ defaults: ["com.android.media-defaults"],
+}
+
+apex_defaults {
+ name: "com.android.media.swcodec-defaults",
native_shared_libs: [
"libmedia_codecserviceregistrant",
],
use_vendor: true,
key: "com.android.media.swcodec.key",
+ certificate: ":com.android.media.swcodec.certificate",
+}
+
+apex {
+ name: "com.android.media.swcodec",
+ manifest: "manifest_codec.json",
+ defaults: ["com.android.media.swcodec-defaults"],
}
apex_key {
@@ -65,3 +77,13 @@
public_key: "com.android.media.swcodec.avbpubkey",
private_key: "com.android.media.swcodec.pem",
}
+
+android_app_certificate {
+ name: "com.android.media.certificate",
+ certificate: "com.android.media",
+}
+
+android_app_certificate {
+ name: "com.android.media.swcodec.certificate",
+ certificate: "com.android.media.swcodec",
+}
diff --git a/apex/com.android.media.pk8 b/apex/com.android.media.pk8
new file mode 100644
index 0000000..6df741e
--- /dev/null
+++ b/apex/com.android.media.pk8
Binary files differ
diff --git a/apex/com.android.media.swcodec.pk8 b/apex/com.android.media.swcodec.pk8
new file mode 100644
index 0000000..05a4216
--- /dev/null
+++ b/apex/com.android.media.swcodec.pk8
Binary files differ
diff --git a/apex/com.android.media.swcodec.x509.pem b/apex/com.android.media.swcodec.x509.pem
new file mode 100644
index 0000000..67b9b4f
--- /dev/null
+++ b/apex/com.android.media.swcodec.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIJAIM72JpD4v6XMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
+VmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEiMCAGA1UE
+AwwZY29tLmFuZHJvaWQubWVkaWEuc3djb2RlYzAgFw0xOTAyMTEwMjExMTFaGA80
+NzU3MDEwNzAyMTExMVowgYIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9y
+bmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAw
+DgYDVQQLDAdBbmRyb2lkMSIwIAYDVQQDDBljb20uYW5kcm9pZC5tZWRpYS5zd2Nv
+ZGVjMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsqXE0AIWpLW9Tgq2
+nQGph7KZ6L2Q9oxviqCVHxIaPqfhM2SwTbycADIQeqrrlRxhddVkjLuMUkJa7mev
+fERmgpiOfnPIlGK6PTs2gljCkskZhF3bgfeyuHt0tsYO+UaN8MVoZD7/QdiE46w2
+OMDClG1UqgiqOBhLTEN/cHXObnUiiVXUYqN8aYZf6L6Fs3yQi2ZZgfbxTVFewqdv
+aLLOqCYnVYXZH+ZxbXESA0M+WXKgRKsYTj2GYs3eko1rFi4Y6uHVLx45yaoT5u/i
+SxPEkocyMCKvGJWu4XlSOd3EjSOMaqCOYVyGLxdlnQWQU7PZDqBSJ0SysWgpFHpB
+I15c2jhRdXOCfQ9ZtDfPZkE0a2A8kJDAoF1mzTp6IvBAWUsl5nHPw5CWkFpNad/h
+tqqGCScWbiKZuvrQ4/RQNm3f1K+mxX9TrjFigpqNO6d4pGAo1fa6sHR3xWPw/myq
+h5ZJjVnXU5Yq64S4xWOssfjpOg7RfNuvzuk3ok3MYs1mbx3vhZOj5km1f3qrgX9c
+mXjYnyXD0jJBm4uAJWXLdK9PlZvlXbztMCzYj832Io4pFLCtSxkzX75t1em36Nv0
+mNp6NtSSy6SFSq8l7IsXV2FNyUiyHWxS/UQm8pYg5Q5dWHvEEF78P6lV0wRa6FQl
+BBSgpqTAI092KIjDDtB7GQCgV5ECAwEAAaNTMFEwHQYDVR0OBBYEFAFIdFTDEDft
+ewSSAS7Fa3OZ5TXzMB8GA1UdIwQYMBaAFAFIdFTDEDftewSSAS7Fa3OZ5TXzMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAC5e3zXythJCGmz1FmAV
+8Y/UI+Glg6G0x/k04WaRG0DPLLjlJ1F0LM1/IReBSgXcYAL0CAgPycf/rGPOgMFm
+tQxYyjBUxKdjpIqU5DJoV1feanGveIRpto1YRKNgHuzG9rZGR4AgPnt6X4Yxlq04
+lI7QpWadXe1myARJhj3niSNY9+2wEInkx4ZuCO1LtIGqnbdc8jQ8YoVqIE5N4kuM
+ccyPYgsdABtopbjN92rueu8sfF8R6ROy+tNgb6OjpAAevtnBfZ2LXqfObKirHCK+
+k6w4WSB1UUoZ3Xgz8sJtXgokvYeInkN8tHuTagHYU2VQTcA0rdBGMN/1OljJpWlN
+0UUq4fAYU6cN4lHxr2LM9If4WvAzdLAWvaIZrDqaU4i/zYT9l6rR4lC2KW3EHWov
+nPXfgEJJ8AP1iRGibvew3i3SB6XTWFQYTUIBeJfDz/KDXQabP+yzXWISdZCUMUpx
+f+Raqsb5MoKaJdVgnSL0mBunjCyJDzzg34J7oGx6/BnwoiOrwLN4Qaz5U8jbrPSx
+p9LfleCcO7ZdeE8GKqx0X1T4d7tradtmxOS8Iwr4niskkHGRkzozvVvuyGKmoN2k
+162Vfjq+ddj7qEpSh3BS6hHU+vlMbC9L0trGxPxFEAHDrwu0KwGNduTkiu/3jvfB
+JTgH8P9mD1loYxRdo+vet8eQ
+-----END CERTIFICATE-----
diff --git a/apex/com.android.media.x509.pem b/apex/com.android.media.x509.pem
new file mode 100644
index 0000000..e7908fa
--- /dev/null
+++ b/apex/com.android.media.x509.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIFzDCCA7SgAwIBAgIJAO05DBBusaaLMA0GCSqGSIb3DQEBCwUAMHoxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRyb2lkMRowGAYDVQQD
+DBFjb20uYW5kcm9pZC5tZWRpYTAgFw0xOTAxMjUxNzE3MTdaGA80NzU2MTIyMTE3
+MTcxN1owejELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNV
+BAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJvaWQxEDAOBgNVBAsMB0Fu
+ZHJvaWQxGjAYBgNVBAMMEWNvbS5hbmRyb2lkLm1lZGlhMIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEAmNkVxUbp/bLbeGbvKqYXzwBycSDpmOhh///lNGYQ
+/AMUD0q6EaZzU2bd4aL0rOGqfoYlhKd0kMVmMUmfdE9ODAfKxleEeEaRl2GJS8a9
+ABi770l3GHbB2xMI2sEWeOD9xsPFF6+ByPZmoUuNhMr4pUbXsDpE3h8ljrgXHtIg
+bh7ofbvddruwBV0lS1k9OZ9jPVGhEKkJnhgQa67cwgdjizAMbI0Dcz9gtMMawsDj
+Z2aQd1r+vxgh1/XkI/NMmXCnG2ERytXcJeC5S4gEtHfTTPoP0FuVgSB6y6dalMuZ
+F0NBZw8Mvgdy3QJip0uNa36J63CMZKTJWbTdlFpPL2hk0PgaYvje8C5Xtk5282wT
+dMocc8n2zIXbzbnSXGvjcNZib3Pfu55YUnX6eTqZ1BxlJ0FHZAsC4quFFWXxYBYD
+LCRoNNFEtIDQpuvuHF2DuHNDULpAQjy2y6+7eot0KEsVoDmZ4H8BpuAVVu2SxYNb
+gYflR9SmM0tmYeAcRT48q3xrocGyEHMqvgQRUpPfvct/8l8xVcDzOI/sJVDqmYzM
+u0Cj3fkSypGDJOMF/esFSmVvoI01tS7kaNS5vvtKYib//xqKRC9f0dCsGfFLnuUK
+o4KYbYWYwMyJqEd/5/ZvXyKIPAEeJL174L9+wTkc3cQpoBwJN4t+2E5MnhOEq6do
+5L0CAwEAAaNTMFEwHQYDVR0OBBYEFHjNK/GZko1RdZp+8iavWXL5xz9wMB8GA1Ud
+IwQYMBaAFHjNK/GZko1RdZp+8iavWXL5xz9wMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQELBQADggIBACmPQMksuLrNV1vbI44S1f70I0FHdBxchFGB39zuLbcn
+SsYom/LPtYJiD0Dl4bB4eb+ZnxkQP2XeP6pycmUH2j1EWexFwvdUvlfe8Qz+wAec
+ap4AxiX4Z2Ke2ivYotIZFUHdZOLkX20js8Wex1mzY43MLQn5APl9gK1VZTxDggeR
+EObH1S+JVjGwQqYZj2e6gNZH34Q25NQ698RL85GDkYtSISAifJtaJsU/B3vKm82I
+k9xMiCooCH6bRdGHG1jze4SRpidjxEm8cxkiaQagfcuXeCLziXJr3qAMKYiEY6bp
+0+bAqCt3S8OrrN3RQZfQrnlwitsM1jJJ/+C+WoDg4eY5AFrXDLvNeKh1qO/f8xv+
+fCXkQPcVVphLfRH9oxNrSgOWBP5/qIDH4s1YUL9luGT6H+08dlue3RkbzDbBqsQu
+7fQ/BbrIG/GuVKgyEM+a7C9gv7zc86YlueVYJEyxKidnn7RxOqyDBqyyfXA3zvme
+Rro7xIrMHPL7Nu3AWjwjXzbp/w0z+tEFPsfVB+OOHKsWPcUG0HUTJGkyeO/uHRjN
+qPEkkf7BHHUO4V2gjOIdCsELxKwHf7vsZTOk40EV751fZ7FDHMr1eddQkgH4eqAb
+DB79uP+SLfUo+42n4q6eMmoqw8d76bBXRoUhIo/Ms4sebhV0sRtAS67OQioc9UUg
+-----END CERTIFICATE-----
diff --git a/apex/testing/Android.bp b/apex/testing/Android.bp
new file mode 100644
index 0000000..701ced7
--- /dev/null
+++ b/apex/testing/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2018 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.
+
+apex {
+ name: "test_com.android.media",
+ manifest: "test_manifest.json",
+ file_contexts: "com.android.media",
+ defaults: ["com.android.media-defaults"],
+ installable: false,
+}
+
+apex {
+ name: "test_com.android.media.swcodec",
+ manifest: "test_manifest_codec.json",
+ file_contexts: "com.android.media.swcodec",
+ defaults: ["com.android.media.swcodec-defaults"],
+ installable: false,
+}
diff --git a/apex/testing/test_manifest.json b/apex/testing/test_manifest.json
new file mode 100644
index 0000000..9f81f9f
--- /dev/null
+++ b/apex/testing/test_manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.media",
+ "version": 2
+}
diff --git a/apex/testing/test_manifest_codec.json b/apex/testing/test_manifest_codec.json
new file mode 100644
index 0000000..c956454
--- /dev/null
+++ b/apex/testing/test_manifest_codec.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.media.swcodec",
+ "version": 2
+}
diff --git a/media/codec2/components/base/SimpleC2Component.cpp b/media/codec2/components/base/SimpleC2Component.cpp
index b8baec8..b158f8f 100644
--- a/media/codec2/components/base/SimpleC2Component.cpp
+++ b/media/codec2/components/base/SimpleC2Component.cpp
@@ -151,7 +151,7 @@
c2_status_t status;
do {
status = mBase->fetchLinearBlock(capacity, usage, block);
- } while (status == C2_TIMED_OUT);
+ } while (status == C2_BLOCKING);
return status;
}
@@ -162,7 +162,7 @@
c2_status_t status;
do {
status = mBase->fetchCircularBlock(capacity, usage, block);
- } while (status == C2_TIMED_OUT);
+ } while (status == C2_BLOCKING);
return status;
}
@@ -174,7 +174,7 @@
do {
status = mBase->fetchGraphicBlock(width, height, format, usage,
block);
- } while (status == C2_TIMED_OUT);
+ } while (status == C2_BLOCKING);
return status;
}
diff --git a/media/codec2/core/include/C2Buffer.h b/media/codec2/core/include/C2Buffer.h
index 2997f6e..c428122 100644
--- a/media/codec2/core/include/C2Buffer.h
+++ b/media/codec2/core/include/C2Buffer.h
@@ -888,6 +888,7 @@
* \retval C2_OK the operation was successful
* \retval C2_NO_MEMORY not enough memory to complete any required allocation
* \retval C2_TIMED_OUT the operation timed out
+ * \retval C2_BLOCKING the operation is blocked
* \retval C2_REFUSED no permission to complete any required allocation
* \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
* \retval C2_OMITTED this pool does not support linear blocks
@@ -916,6 +917,7 @@
* \retval C2_OK the operation was successful
* \retval C2_NO_MEMORY not enough memory to complete any required allocation
* \retval C2_TIMED_OUT the operation timed out
+ * \retval C2_BLOCKING the operation is blocked
* \retval C2_REFUSED no permission to complete any required allocation
* \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
* \retval C2_OMITTED this pool does not support circular blocks
@@ -946,6 +948,7 @@
* \retval C2_OK the operation was successful
* \retval C2_NO_MEMORY not enough memory to complete any required allocation
* \retval C2_TIMED_OUT the operation timed out
+ * \retval C2_BLOCKING the operation is blocked
* \retval C2_REFUSED no permission to complete any required allocation
* \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller
* error)
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
index 02cdc23..343bcb5 100644
--- a/media/codec2/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -1803,7 +1803,8 @@
}
sp<HGraphicBufferProducer> getHgbp(const sp<IGraphicBufferProducer>& igbp) {
- sp<HGraphicBufferProducer> hgbp = igbp->getHalInterface();
+ sp<HGraphicBufferProducer> hgbp =
+ igbp->getHalInterface<HGraphicBufferProducer>();
return hgbp ? hgbp :
new TWGraphicBufferProducer<HGraphicBufferProducer>(igbp);
}
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index 3808be5..7a2e549 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -1064,7 +1064,9 @@
C2BlockPool::local_id_t blockPoolId,
const sp<IGraphicBufferProducer>& surface,
uint32_t generation) {
- sp<HGraphicBufferProducer> igbp = surface->getHalInterface();
+ sp<HGraphicBufferProducer> igbp =
+ surface->getHalInterface<HGraphicBufferProducer>();
+
if (!igbp) {
igbp = new TWGraphicBufferProducer<HGraphicBufferProducer>(surface);
}
diff --git a/media/codec2/vndk/platform/C2BqBuffer.cpp b/media/codec2/vndk/platform/C2BqBuffer.cpp
index 7bf3d64..41a5b3f 100644
--- a/media/codec2/vndk/platform/C2BqBuffer.cpp
+++ b/media/codec2/vndk/platform/C2BqBuffer.cpp
@@ -207,12 +207,16 @@
// dequeueBuffer returns flag.
if (!transStatus.isOk() || status < android::OK) {
ALOGD("cannot dequeue buffer %d", status);
- if (transStatus.isOk() && status == android::INVALID_OPERATION) {
- // Too many buffer dequeued. retrying after some time is required.
- return C2_TIMED_OUT;
- } else {
- return C2_BAD_VALUE;
+ if (transStatus.isOk()) {
+ if (status == android::INVALID_OPERATION ||
+ status == android::TIMED_OUT ||
+ status == android::WOULD_BLOCK) {
+ // Dequeue buffer is blocked temporarily. Retrying is
+ // required.
+ return C2_BLOCKING;
+ }
}
+ return C2_BAD_VALUE;
}
ALOGV("dequeued a buffer successfully");
native_handle_t* nh = nullptr;
@@ -227,7 +231,7 @@
if (status == -ETIME) {
// fence is not signalled yet.
(void)mProducer->cancelBuffer(slot, fenceHandle).isOk();
- return C2_TIMED_OUT;
+ return C2_BLOCKING;
}
if (status != android::NO_ERROR) {
ALOGD("buffer fence wait error %d", status);
@@ -353,14 +357,14 @@
return C2_OK;
}
c2_status_t status = fetchFromIgbp_l(width, height, format, usage, block);
- if (status == C2_TIMED_OUT) {
+ if (status == C2_BLOCKING) {
lock.unlock();
::usleep(kMaxIgbpRetryDelayUs);
continue;
}
return status;
}
- return C2_TIMED_OUT;
+ return C2_BLOCKING;
}
void setRenderCallback(const OnRenderCallback &renderCallback) {
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index bd10d67..b111b78 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -74,6 +74,7 @@
"libnblog",
"libprocessgroup",
"libutils",
+ "libvibrator",
],
export_shared_lib_headers: ["libbinder"],
diff --git a/media/libaudioclient/include/media/AudioMixer.h b/media/libaudioclient/include/media/AudioMixer.h
index fbbbd11..41b425f 100644
--- a/media/libaudioclient/include/media/AudioMixer.h
+++ b/media/libaudioclient/include/media/AudioMixer.h
@@ -26,6 +26,7 @@
#include <unordered_map>
#include <vector>
+#include <android/os/IExternalVibratorService.h>
#include <media/AudioBufferProvider.h>
#include <media/AudioResampler.h>
#include <media/AudioResamplerPublic.h>
@@ -103,20 +104,21 @@
// parameter 'value' is a pointer to the new playback rate.
};
- enum { // Haptic intensity, should keep consistent with VibratorService
- HAPTIC_SCALE_VERY_LOW = -2,
- HAPTIC_SCALE_LOW = -1,
- HAPTIC_SCALE_NONE = 0,
- HAPTIC_SCALE_HIGH = 1,
- HAPTIC_SCALE_VERY_HIGH = 2,
- };
- typedef int32_t haptic_intensity_t;
- static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2 / 3;
- static constexpr float HAPTIC_SCALE_LOW_RATIO = 3 / 4;
- static const CONSTEXPR float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f;
+ typedef enum { // Haptic intensity, should keep consistent with VibratorService
+ HAPTIC_SCALE_MUTE = os::IExternalVibratorService::SCALE_MUTE,
+ HAPTIC_SCALE_VERY_LOW = os::IExternalVibratorService::SCALE_VERY_LOW,
+ HAPTIC_SCALE_LOW = os::IExternalVibratorService::SCALE_LOW,
+ HAPTIC_SCALE_NONE = os::IExternalVibratorService::SCALE_NONE,
+ HAPTIC_SCALE_HIGH = os::IExternalVibratorService::SCALE_HIGH,
+ HAPTIC_SCALE_VERY_HIGH = os::IExternalVibratorService::SCALE_VERY_HIGH,
+ } haptic_intensity_t;
+ static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2.0f / 3.0f;
+ static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f;
+ static const constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f;
static inline bool isValidHapticIntensity(haptic_intensity_t hapticIntensity) {
switch (hapticIntensity) {
+ case HAPTIC_SCALE_MUTE:
case HAPTIC_SCALE_VERY_LOW:
case HAPTIC_SCALE_LOW:
case HAPTIC_SCALE_NONE:
@@ -428,8 +430,9 @@
case HAPTIC_SCALE_NONE:
case HAPTIC_SCALE_HIGH:
case HAPTIC_SCALE_VERY_HIGH:
- default:
return 1.0f;
+ default:
+ return 0.0f;
}
}
diff --git a/media/libaudioprocessing/Android.bp b/media/libaudioprocessing/Android.bp
index 817fb0b..cb78063 100644
--- a/media/libaudioprocessing/Android.bp
+++ b/media/libaudioprocessing/Android.bp
@@ -12,6 +12,11 @@
"libnblog",
"libsonic",
"libutils",
+ "libvibrator",
+ ],
+
+ header_libs: [
+ "libbase_headers",
],
cflags: [
diff --git a/media/libaudioprocessing/AudioMixer.cpp b/media/libaudioprocessing/AudioMixer.cpp
index 86777d6..2c57db7 100644
--- a/media/libaudioprocessing/AudioMixer.cpp
+++ b/media/libaudioprocessing/AudioMixer.cpp
@@ -113,10 +113,10 @@
// Integer volume.
// Currently integer volume is kept for the legacy integer mixer.
// Will be removed when the legacy mixer path is removed.
- t->volume[0] = UNITY_GAIN_INT;
- t->volume[1] = UNITY_GAIN_INT;
- t->prevVolume[0] = UNITY_GAIN_INT << 16;
- t->prevVolume[1] = UNITY_GAIN_INT << 16;
+ t->volume[0] = 0;
+ t->volume[1] = 0;
+ t->prevVolume[0] = 0 << 16;
+ t->prevVolume[1] = 0 << 16;
t->volumeInc[0] = 0;
t->volumeInc[1] = 0;
t->auxLevel = 0;
@@ -124,10 +124,10 @@
t->prevAuxLevel = 0;
// Floating point volume.
- t->mVolume[0] = UNITY_GAIN_FLOAT;
- t->mVolume[1] = UNITY_GAIN_FLOAT;
- t->mPrevVolume[0] = UNITY_GAIN_FLOAT;
- t->mPrevVolume[1] = UNITY_GAIN_FLOAT;
+ t->mVolume[0] = 0.f;
+ t->mVolume[1] = 0.f;
+ t->mPrevVolume[0] = 0.f;
+ t->mPrevVolume[1] = 0.f;
t->mVolumeInc[0] = 0.;
t->mVolumeInc[1] = 0.;
t->mAuxLevel = 0.;
diff --git a/media/libaudioprocessing/tests/Android.bp b/media/libaudioprocessing/tests/Android.bp
index 811c16b..0c8e5bb 100644
--- a/media/libaudioprocessing/tests/Android.bp
+++ b/media/libaudioprocessing/tests/Android.bp
@@ -10,6 +10,7 @@
"libcutils",
"liblog",
"libutils",
+ "libvibrator",
],
cflags: [
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.c b/media/libeffects/lvm/lib/Common/src/Copy_16.c
index 1f9f659..3858450 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.c
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.c
@@ -132,8 +132,8 @@
src += NrChannels * (NrFrames - 1);
for (ii = NrFrames; ii != 0; ii--)
{
- dst[0] = src_st[0];
dst[1] = src_st[1];
+ dst[0] = src_st[0]; // copy 1 before 0 is required for NrChannels == 3.
for (jj = 2; jj < NrChannels; jj++)
{
dst[jj] = src[jj];
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
index 41a4f04..1a874a3 100755
--- a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
@@ -54,21 +54,13 @@
192000
)
-ch_arr=(
- 1
- 2
- 4
- 6
- 8
-)
-
# run multichannel effects at different configs, saving only the stereo channel
# pair.
for flags in "${flags_arr[@]}"
do
for fs in ${fs_arr[*]}
do
- for ch in ${ch_arr[*]}
+ for ch in {1..8}
do
adb shell $testdir/lvmtest -i:$testdir/sinesweepraw.raw \
-o:$testdir/sinesweep_$((ch))_$((fs)).raw -ch:$ch -fs:$fs $flags
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index a073081..747b88f 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -552,7 +552,7 @@
};
IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
-IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, IOmxNode, "android.hardware.IOMXNode");
+IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, "android.hardware.IOMXNode");
////////////////////////////////////////////////////////////////////////////////
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 08c6a50..98c5497 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -92,6 +92,19 @@
{"highspeed720p", CAMCORDER_QUALITY_HIGH_SPEED_720P},
{"highspeed1080p", CAMCORDER_QUALITY_HIGH_SPEED_1080P},
{"highspeed2160p", CAMCORDER_QUALITY_HIGH_SPEED_2160P},
+
+ // Vendor-specific profiles
+ {"vga", CAMCORDER_QUALITY_VGA},
+ {"4kdci", CAMCORDER_QUALITY_4KDCI},
+ {"timelapsevga", CAMCORDER_QUALITY_TIME_LAPSE_VGA},
+ {"timelapse4kdci", CAMCORDER_QUALITY_TIME_LAPSE_4KDCI},
+ {"highspeedcif", CAMCORDER_QUALITY_HIGH_SPEED_CIF},
+ {"highspeedvga", CAMCORDER_QUALITY_HIGH_SPEED_VGA},
+ {"highspeed4kdci", CAMCORDER_QUALITY_HIGH_SPEED_4KDCI},
+ {"qhd", CAMCORDER_QUALITY_QHD},
+ {"2k", CAMCORDER_QUALITY_2k},
+ {"timelapseqhd", CAMCORDER_QUALITY_TIME_LAPSE_QHD},
+ {"timelapse2k", CAMCORDER_QUALITY_TIME_LAPSE_2k},
};
#if LOG_NDEBUG
diff --git a/media/libmedia/include/media/MediaProfiles.h b/media/libmedia/include/media/MediaProfiles.h
index 0feb4f3..3e8e7c8 100644
--- a/media/libmedia/include/media/MediaProfiles.h
+++ b/media/libmedia/include/media/MediaProfiles.h
@@ -34,7 +34,11 @@
CAMCORDER_QUALITY_1080P = 6,
CAMCORDER_QUALITY_QVGA = 7,
CAMCORDER_QUALITY_2160P = 8,
- CAMCORDER_QUALITY_LIST_END = 8,
+ CAMCORDER_QUALITY_VGA = 9,
+ CAMCORDER_QUALITY_4KDCI = 10,
+ CAMCORDER_QUALITY_QHD = 11,
+ CAMCORDER_QUALITY_2k = 12,
+ CAMCORDER_QUALITY_LIST_END = 12,
CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000,
@@ -46,7 +50,11 @@
CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007,
CAMCORDER_QUALITY_TIME_LAPSE_2160P = 1008,
- CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1008,
+ CAMCORDER_QUALITY_TIME_LAPSE_VGA = 1009,
+ CAMCORDER_QUALITY_TIME_LAPSE_4KDCI = 1010,
+ CAMCORDER_QUALITY_TIME_LAPSE_QHD = 1011,
+ CAMCORDER_QUALITY_TIME_LAPSE_2k = 1012,
+ CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1012,
CAMCORDER_QUALITY_HIGH_SPEED_LIST_START = 2000,
CAMCORDER_QUALITY_HIGH_SPEED_LOW = 2000,
@@ -55,7 +63,10 @@
CAMCORDER_QUALITY_HIGH_SPEED_720P = 2003,
CAMCORDER_QUALITY_HIGH_SPEED_1080P = 2004,
CAMCORDER_QUALITY_HIGH_SPEED_2160P = 2005,
- CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005,
+ CAMCORDER_QUALITY_HIGH_SPEED_CIF = 2006,
+ CAMCORDER_QUALITY_HIGH_SPEED_VGA = 2007,
+ CAMCORDER_QUALITY_HIGH_SPEED_4KDCI = 2008,
+ CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2008,
};
enum video_decoder {
diff --git a/media/libmedia/include/media/omx/1.0/WOmxNode.h b/media/libmedia/include/media/omx/1.0/WOmxNode.h
index eebc8c6..1db4248 100644
--- a/media/libmedia/include/media/omx/1.0/WOmxNode.h
+++ b/media/libmedia/include/media/omx/1.0/WOmxNode.h
@@ -59,7 +59,7 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-struct LWOmxNode : public H2BConverter<IOmxNode, IOMXNode, BnOMXNode> {
+struct LWOmxNode : public H2BConverter<IOmxNode, BnOMXNode> {
LWOmxNode(sp<IOmxNode> const& base) : CBase(base) {}
status_t freeNode() override;
status_t sendCommand(
diff --git a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
index 31d1df9..1ed1d07 100644
--- a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
+++ b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
@@ -32,7 +32,7 @@
BnStatus LWGraphicBufferSource::configure(
const sp<IOMXNode>& omxNode, int32_t dataSpace) {
- sp<IOmxNode> hOmxNode = omxNode->getHalInterface();
+ sp<IOmxNode> hOmxNode = omxNode->getHalInterface<IOmxNode>();
return toBinderStatus(mBase->configure(
hOmxNode == nullptr ? new TWOmxNode(omxNode) : hOmxNode,
toHardwareDataspace(dataSpace)));
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 52cb5fa..998f096 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -4431,9 +4431,9 @@
h264type.nRefFrames = 2;
h264type.nBFrames = mLatency == 0 ? 1 : std::min(1U, mLatency - 1);
- // disable B-frames until MPEG4Writer can guarantee finalizing files with B-frames
- // h264type.nRefFrames = 1;
- // h264type.nBFrames = 0;
+ // disable B-frames until we have explicit settings for enabling the feature.
+ h264type.nRefFrames = 1;
+ h264type.nBFrames = 0;
h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
h264type.nAllowedPictureTypes =
@@ -6539,8 +6539,10 @@
if (mDeathNotifier != NULL) {
if (mCodec->mOMXNode != NULL) {
- auto tOmxNode = mCodec->mOMXNode->getHalInterface();
- tOmxNode->unlinkToDeath(mDeathNotifier);
+ auto tOmxNode = mCodec->mOMXNode->getHalInterface<IOmxNode>();
+ if (tOmxNode) {
+ tOmxNode->unlinkToDeath(mDeathNotifier);
+ }
}
mDeathNotifier.clear();
}
@@ -6668,8 +6670,8 @@
}
mDeathNotifier = new DeathNotifier(notify);
- auto tOmxNode = omxNode->getHalInterface();
- if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
+ auto tOmxNode = omxNode->getHalInterface<IOmxNode>();
+ if (tOmxNode && !tOmxNode->linkToDeath(mDeathNotifier, 0)) {
mDeathNotifier.clear();
}
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 74754ea..339f622 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -106,6 +106,10 @@
symbol_file: "libmediandk.map.txt",
versions: ["29"],
},
+
+ // Bug: http://b/124522995 libmediandk has linker errors when built with
+ // coverage
+ native_coverage: false,
}
llndk_library {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 2d80bd8..4033247 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -347,7 +347,7 @@
return ret;
}
}
- return AudioMixer::HAPTIC_SCALE_NONE;
+ return AudioMixer::HAPTIC_SCALE_MUTE;
}
/* static */
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index c27f2b7..396c797 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -49,7 +49,7 @@
audio_format_t mFormat; // track format
int mGeneration; // increment when any field is assigned
bool mHapticPlaybackEnabled = false; // haptic playback is enabled or not
- AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_NONE; // intensity of
+ AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_MUTE; // intensity of
// haptic data
};
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 3381e4d..676a575 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -211,8 +211,8 @@
((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
((patch->sinks[0].ext.device.hw_module != srcModule) ||
!audioHwDevice->supportsAudioPatches()))) {
- audio_devices_t outputDevice = AUDIO_DEVICE_NONE;
- String8 outputDeviceAddress;
+ audio_devices_t outputDevice = patch->sinks[0].ext.device.type;
+ String8 outputDeviceAddress = String8(patch->sinks[0].ext.device.address);
if (patch->num_sources == 2) {
if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX ||
(patch->num_sinks != 0 && patch->sinks[0].ext.device.hw_module !=
@@ -234,8 +234,6 @@
reinterpret_cast<PlaybackThread*>(thread.get()), false /*closeThread*/);
} else {
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
- audio_devices_t device = patch->sinks[0].ext.device.type;
- String8 address = String8(patch->sinks[0].ext.device.address);
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
@@ -254,8 +252,8 @@
patch->sinks[0].ext.device.hw_module,
&output,
&config,
- device,
- address,
+ outputDevice,
+ outputDeviceAddress,
flags);
ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
if (thread == 0) {
@@ -263,8 +261,6 @@
goto exit;
}
newPatch.mPlayback.setThread(reinterpret_cast<PlaybackThread*>(thread.get()));
- outputDevice = device;
- outputDeviceAddress = address;
}
audio_devices_t device = patch->sources[0].ext.device.type;
String8 address = String8(patch->sources[0].ext.device.address);
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 94ea042..357370e 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -124,6 +124,7 @@
void setHapticIntensity(AudioMixer::haptic_intensity_t hapticIntensity) {
if (AudioMixer::isValidHapticIntensity(hapticIntensity)) {
mHapticIntensity = hapticIntensity;
+ setHapticPlaybackEnabled(mHapticIntensity != AudioMixer::HAPTIC_SCALE_MUTE);
}
}
sp<os::ExternalVibration> getExternalVibration() const { return mExternalVibration; }
@@ -208,7 +209,7 @@
bool mHapticPlaybackEnabled = false; // indicates haptic playback enabled or not
// intensity to play haptic data
- AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_NONE;
+ AudioMixer::haptic_intensity_t mHapticIntensity = AudioMixer::HAPTIC_SCALE_MUTE;
class AudioVibrationController : public os::BnExternalVibrationController {
public:
explicit AudioVibrationController(Track* track) : mTrack(track) {}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 6dd9cab..a8c4bd1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2372,6 +2372,7 @@
const int intensity = AudioFlinger::onExternalVibrationStart(
track->getExternalVibration());
mLock.lock();
+ track->setHapticIntensity(static_cast<AudioMixer::haptic_intensity_t>(intensity));
// Haptic playback should be enabled by vibrator service.
if (track->getHapticPlaybackEnabled()) {
// Disable haptic playback of all active track to ensure only
@@ -2380,7 +2381,6 @@
t->setHapticPlaybackEnabled(false);
}
}
- track->setHapticIntensity(intensity);
}
track->mResetDone = false;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 922547d..65f799e 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -698,6 +698,7 @@
// TODO: compensate for time shift between HW modules.
void AudioFlinger::PlaybackThread::Track::interceptBuffer(
const AudioBufferProvider::Buffer& sourceBuffer) {
+ auto start = std::chrono::steady_clock::now();
const size_t frameCount = sourceBuffer.frameCount;
for (auto& sink : mTeePatches) {
RecordThread::PatchRecord* patchRecord = sink.patchRecord.get();
@@ -715,6 +716,11 @@
"buffer %zu/%zu, dropping %zu frames", __func__, mId, patchRecord->mId,
framesWritten, frameCount, framesLeft);
}
+ auto spent = ceil<std::chrono::microseconds>(std::chrono::steady_clock::now() - start);
+ using namespace std::chrono_literals;
+ // Average is ~20us per track, this should virtually never be logged (Logging takes >200us)
+ ALOGD_IF(spent > 200us, "%s: took %lldus to intercept %zu tracks", __func__,
+ spent.count(), mTeePatches.size());
}
size_t AudioFlinger::PlaybackThread::Track::writeFrames(AudioBufferProvider* dest,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5c22727..32cc380 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -560,6 +560,10 @@
muteWaitMs = setOutputDevices(mPrimaryOutput, rxDevices, true, delayMs);
} else { // create RX path audio patch
mCallRxPatch = createTelephonyPatch(true /*isRx*/, rxDevices.itemAt(0), delayMs);
+
+ // If the TX device is on the primary HW module but RX device is
+ // on other HW module, SinkMetaData of telephony input should handle it
+ // assuming the device uses audio HAL V5.0 and above
}
if (createTxPatch) { // create TX path audio patch
mCallTxPatch = createTelephonyPatch(false /*isRx*/, txSourceDevice, delayMs);
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index a39477d..76ac191 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -383,6 +383,8 @@
// OR The client is an accessibility service
// AND is on TOP OR latest started
// AND the source is VOICE_RECOGNITION or HOTWORD
+// OR the source is one of: AUDIO_SOURCE_VOICE_DOWNLINK, AUDIO_SOURCE_VOICE_UPLINK,
+// AUDIO_SOURCE_VOICE_CALL
// OR Any other client
// AND The assistant is not on TOP
// AND is on TOP OR latest started
@@ -463,6 +465,10 @@
(source == AUDIO_SOURCE_VOICE_RECOGNITION || source == AUDIO_SOURCE_HOTWORD)) {
forceIdle = false;
}
+ } else if (source == AUDIO_SOURCE_VOICE_DOWNLINK ||
+ source == AUDIO_SOURCE_VOICE_CALL ||
+ (source == AUDIO_SOURCE_VOICE_UPLINK)) {
+ forceIdle = false;
} else {
if (!isAssistantOnTop && (isOnTop || isLatest) &&
(!isSensitiveActive || isLatestSensitive)) {
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 8e9c39e..a61cdee 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -136,6 +136,8 @@
mAppSegmentConsumer->setName(String8("Camera3-HeicComposite-AppSegmentStream"));
mAppSegmentSurface = new Surface(producer);
+ mStaticInfo = device->info();
+
res = device->createStream(mAppSegmentSurface, mAppSegmentMaxSize, 1, format,
kAppSegmentDataSpace, rotation, &mAppSegmentStreamId, physicalCameraId, surfaceIds);
if (res == OK) {
@@ -606,9 +608,42 @@
mFrameNumberMap.erase(it);
}
- // Heic composition doesn't depend on capture result, so no need to check
- // mErrorFrameNumbers. Just remove them.
- mErrorFrameNumbers.clear();
+ while (!mCaptureResults.empty()) {
+ auto it = mCaptureResults.begin();
+ // Negative timestamp indicates that something went wrong during the capture result
+ // collection process.
+ if (it->first >= 0) {
+ if (mPendingInputFrames[it->first].frameNumber == std::get<0>(it->second)) {
+ mPendingInputFrames[it->first].result =
+ std::make_unique<CameraMetadata>(std::get<1>(it->second));
+ } else {
+ ALOGE("%s: Capture result frameNumber/timestamp mapping changed between "
+ "shutter and capture result!", __FUNCTION__);
+ }
+ }
+ mCaptureResults.erase(it);
+ }
+
+ // mErrorFrameNumbers stores frame number of dropped buffers.
+ auto it = mErrorFrameNumbers.begin();
+ while (it != mErrorFrameNumbers.end()) {
+ bool frameFound = false;
+ for (auto &inputFrame : mPendingInputFrames) {
+ if (inputFrame.second.frameNumber == *it) {
+ inputFrame.second.error = true;
+ frameFound = true;
+ break;
+ }
+ }
+
+ if (frameFound) {
+ it = mErrorFrameNumbers.erase(it);
+ } else {
+ ALOGW("%s: Not able to find failing input with frame number: %" PRId64, __FUNCTION__,
+ *it);
+ it++;
+ }
+ }
// Distribute codec input buffers to be filled out from YUV output
for (auto it = mPendingInputFrames.begin();
@@ -639,14 +674,14 @@
bool newInputAvailable = false;
for (const auto& it : mPendingInputFrames) {
- bool appSegmentBufferReady = (it.second.appSegmentBuffer.data != nullptr) &&
- !it.second.appSegmentWritten;
+ bool appSegmentReady = (it.second.appSegmentBuffer.data != nullptr) &&
+ !it.second.appSegmentWritten && it.second.result != nullptr;
bool codecOutputReady = !it.second.codecOutputBuffers.empty();
bool codecInputReady = (it.second.yuvBuffer.data != nullptr) &&
(!it.second.codecInputBuffers.empty());
if ((!it.second.error) &&
(it.first < *currentTs) &&
- (appSegmentBufferReady || codecOutputReady || codecInputReady)) {
+ (appSegmentReady || codecOutputReady || codecInputReady)) {
*currentTs = it.first;
newInputAvailable = true;
break;
@@ -678,13 +713,13 @@
ATRACE_CALL();
status_t res = OK;
- bool appSegmentBufferReady = inputFrame.appSegmentBuffer.data != nullptr &&
- !inputFrame.appSegmentWritten;
+ bool appSegmentReady = inputFrame.appSegmentBuffer.data != nullptr &&
+ !inputFrame.appSegmentWritten && inputFrame.result != nullptr;
bool codecOutputReady = inputFrame.codecOutputBuffers.size() > 0;
bool codecInputReady = inputFrame.yuvBuffer.data != nullptr &&
!inputFrame.codecInputBuffers.empty();
- if (!appSegmentBufferReady && !codecOutputReady && !codecInputReady) {
+ if (!appSegmentReady && !codecOutputReady && !codecInputReady) {
ALOGW("%s: No valid appSegmentBuffer/codec input/outputBuffer available!", __FUNCTION__);
return OK;
}
@@ -710,7 +745,7 @@
}
// Write JPEG APP segments data to the muxer.
- if (appSegmentBufferReady && inputFrame.muxer != nullptr) {
+ if (appSegmentReady && inputFrame.muxer != nullptr) {
res = processAppSegment(timestamp, inputFrame);
if (res != OK) {
ALOGE("%s: Failed to process JPEG APP segments: %s (%d)", __FUNCTION__,
@@ -829,10 +864,8 @@
ALOGE("%s: Failed to initialize ExifUtils object!", __FUNCTION__);
return BAD_VALUE;
}
- //TODO: Use capture result metadata and static metadata to fill out the
- //rest.
- CameraMetadata dummyMeta;
- exifRes = exifUtils->setFromMetadata(dummyMeta, mOutputWidth, mOutputHeight);
+ exifRes = exifUtils->setFromMetadata(*inputFrame.result, mStaticInfo,
+ mOutputWidth, mOutputHeight);
if (!exifRes) {
ALOGE("%s: Failed to set Exif tags using metadata and main image sizes", __FUNCTION__);
return BAD_VALUE;
@@ -1012,6 +1045,7 @@
}
inputFrame.anb = nullptr;
+ ATRACE_ASYNC_END("HEIC capture", inputFrame.frameNumber);
return OK;
}
@@ -1497,6 +1531,36 @@
return res;
}
+void HeicCompositeStream::onResultError(const CaptureResultExtras& resultExtras) {
+ // For result error, since the APPS_SEGMENT buffer already contains EXIF,
+ // simply skip using the capture result metadata to override EXIF.
+ Mutex::Autolock l(mMutex);
+
+ int64_t timestamp = -1;
+ for (const auto& fn : mFrameNumberMap) {
+ if (fn.first == resultExtras.frameNumber) {
+ timestamp = fn.second;
+ break;
+ }
+ }
+ if (timestamp == -1) {
+ for (const auto& inputFrame : mPendingInputFrames) {
+ if (inputFrame.second.frameNumber == resultExtras.frameNumber) {
+ timestamp = inputFrame.first;
+ break;
+ }
+ }
+ }
+
+ if (timestamp == -1) {
+ ALOGE("%s: Failed to find shutter timestamp for result error!", __FUNCTION__);
+ return;
+ }
+
+ mCaptureResults.emplace(timestamp, std::make_tuple(resultExtras.frameNumber, CameraMetadata()));
+ mInputReadyCondition.signal();
+}
+
void HeicCompositeStream::CodecCallbackHandler::onMessageReceived(const sp<AMessage> &msg) {
sp<HeicCompositeStream> parent = mParent.promote();
if (parent == nullptr) return;
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.h b/services/camera/libcameraservice/api2/HeicCompositeStream.h
index 0a76256..4cd9af0 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.h
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.h
@@ -77,7 +77,7 @@
bool threadLoop() override;
bool onStreamBufferError(const CaptureResultExtras& resultExtras) override;
- void onResultError(const CaptureResultExtras& /*resultExtras*/) override {}
+ void onResultError(const CaptureResultExtras& resultExtras) override;
private:
//
@@ -145,12 +145,13 @@
int32_t orientation;
int32_t quality;
- CpuConsumer::LockedBuffer appSegmentBuffer;
+ CpuConsumer::LockedBuffer appSegmentBuffer;
std::vector<CodecOutputBufferInfo> codecOutputBuffers;
+ std::unique_ptr<CameraMetadata> result;
// Fields that are only applicable to HEVC tiling.
- CpuConsumer::LockedBuffer yuvBuffer;
- std::vector<CodecInputBufferInfo> codecInputBuffers;
+ CpuConsumer::LockedBuffer yuvBuffer;
+ std::vector<CodecInputBufferInfo> codecInputBuffers;
bool error;
bool errorNotified;
@@ -209,6 +210,7 @@
sp<Surface> mAppSegmentSurface;
bool mAppSegmentBufferAcquired;
size_t mAppSegmentMaxSize;
+ CameraMetadata mStaticInfo;
int mMainImageStreamId, mMainImageSurfaceId;
sp<Surface> mMainImageSurface;
diff --git a/services/camera/libcameraservice/utils/ExifUtils.cpp b/services/camera/libcameraservice/utils/ExifUtils.cpp
index a4027cc..4dea8b5 100644
--- a/services/camera/libcameraservice/utils/ExifUtils.cpp
+++ b/services/camera/libcameraservice/utils/ExifUtils.cpp
@@ -58,79 +58,59 @@
// set all known fields from a metadata structure
virtual bool setFromMetadata(const CameraMetadata& metadata,
+ const CameraMetadata& staticInfo,
const size_t imageWidth,
const size_t imageHeight);
// sets the len aperture.
// Returns false if memory allocation fails.
- virtual bool setAperture(uint32_t numerator, uint32_t denominator);
-
- // sets the value of brightness.
- // Returns false if memory allocation fails.
- virtual bool setBrightness(int32_t numerator, int32_t denominator);
+ virtual bool setAperture(float aperture);
// sets the color space.
// Returns false if memory allocation fails.
virtual bool setColorSpace(uint16_t color_space);
- // sets the information to compressed data.
- // Returns false if memory allocation fails.
- virtual bool setComponentsConfiguration(const std::string& components_configuration);
-
- // sets the compression scheme used for the image data.
- // Returns false if memory allocation fails.
- virtual bool setCompression(uint16_t compression);
-
- // sets image contrast.
- // Returns false if memory allocation fails.
- virtual bool setContrast(uint16_t contrast);
-
// sets the date and time of image last modified. It takes local time. The
// name of the tag is DateTime in IFD0.
// Returns false if memory allocation fails.
virtual bool setDateTime(const struct tm& t);
- // sets the image description.
- // Returns false if memory allocation fails.
- virtual bool setDescription(const std::string& description);
-
// sets the digital zoom ratio. If the numerator is 0, it means digital zoom
// was not used.
// Returns false if memory allocation fails.
- virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator);
+ virtual bool setDigitalZoomRatio(
+ uint32_t crop_width, uint32_t crop_height,
+ uint32_t sensor_width, uint32_t sensor_height);
- // sets the exposure bias.
+ // Sets the exposure bias.
// Returns false if memory allocation fails.
- virtual bool setExposureBias(int32_t numerator, int32_t denominator);
+ virtual bool setExposureBias(int32_t ev,
+ uint32_t ev_step_numerator, uint32_t ev_step_denominator);
// sets the exposure mode set when the image was shot.
// Returns false if memory allocation fails.
- virtual bool setExposureMode(uint16_t exposure_mode);
-
- // sets the program used by the camera to set exposure when the picture is
- // taken.
- // Returns false if memory allocation fails.
- virtual bool setExposureProgram(uint16_t exposure_program);
+ virtual bool setExposureMode(uint8_t exposure_mode);
// sets the exposure time, given in seconds.
// Returns false if memory allocation fails.
- virtual bool setExposureTime(uint32_t numerator, uint32_t denominator);
+ virtual bool setExposureTime(float exposure_time);
// sets the status of flash.
// Returns false if memory allocation fails.
- virtual bool setFlash(uint16_t flash);
+ virtual bool setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode);
// sets the F number.
// Returns false if memory allocation fails.
- virtual bool setFNumber(uint32_t numerator, uint32_t denominator);
+ virtual bool setFNumber(float f_number);
// sets the focal length of lens used to take the image in millimeters.
// Returns false if memory allocation fails.
- virtual bool setFocalLength(uint32_t numerator, uint32_t denominator);
+ virtual bool setFocalLength(float focal_length);
- // sets the degree of overall image gain adjustment.
+ // sets the focal length of lens for 35mm film used to take the image in millimeters.
// Returns false if memory allocation fails.
- virtual bool setGainControl(uint16_t gain_control);
+ virtual bool setFocalLengthIn35mmFilm(float focal_length,
+ float sensor_size_x, float sensor_size_y);
// sets the altitude in meters.
// Returns false if memory allocation fails.
@@ -164,45 +144,21 @@
// Returns false if memory allocation fails.
virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings);
- // sets the kind of light source.
- // Returns false if memory allocation fails.
- virtual bool setLightSource(uint16_t light_source);
-
// sets the smallest F number of the lens.
// Returns false if memory allocation fails.
- virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator);
-
- // sets the metering mode.
- // Returns false if memory allocation fails.
- virtual bool setMeteringMode(uint16_t metering_mode);
+ virtual bool setMaxAperture(float aperture);
// sets image orientation.
// Returns false if memory allocation fails.
virtual bool setOrientation(uint16_t orientation);
- // sets the unit for measuring XResolution and YResolution.
- // Returns false if memory allocation fails.
- virtual bool setResolutionUnit(uint16_t resolution_unit);
-
- // sets image saturation.
- // Returns false if memory allocation fails.
- virtual bool setSaturation(uint16_t saturation);
-
- // sets the type of scene that was shot.
- // Returns false if memory allocation fails.
- virtual bool setSceneCaptureType(uint16_t type);
-
- // sets image sharpness.
- // Returns false if memory allocation fails.
- virtual bool setSharpness(uint16_t sharpness);
-
// sets the shutter speed.
// Returns false if memory allocation fails.
- virtual bool setShutterSpeed(int32_t numerator, int32_t denominator);
+ virtual bool setShutterSpeed(float exposure_time);
// sets the distance to the subject, given in meters.
// Returns false if memory allocation fails.
- virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator);
+ virtual bool setSubjectDistance(float diopters);
// sets the fractions of seconds for the <DateTime> tag.
// Returns false if memory allocation fails.
@@ -210,28 +166,7 @@
// sets the white balance mode set when the image was shot.
// Returns false if memory allocation fails.
- virtual bool setWhiteBalance(uint16_t white_balance);
-
- // sets the number of pixels per resolution unit in the image width.
- // Returns false if memory allocation fails.
- virtual bool setXResolution(uint32_t numerator, uint32_t denominator);
-
- // sets the position of chrominance components in relation to the luminance
- // component.
- // Returns false if memory allocation fails.
- virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning);
-
- // sets the number of pixels per resolution unit in the image length.
- // Returns false if memory allocation fails.
- virtual bool setYResolution(uint32_t numerator, uint32_t denominator);
-
- // sets the manufacturer of camera.
- // Returns false if memory allocation fails.
- virtual bool setMake(const std::string& make);
-
- // sets the model number of camera.
- // Returns false if memory allocation fails.
- virtual bool setModel(const std::string& model);
+ virtual bool setWhiteBalance(uint8_t white_balance);
// Generates APP1 segment.
// Returns false if generating APP1 segment fails.
@@ -280,6 +215,10 @@
virtual bool setString(ExifIfd ifd, ExifTag tag, ExifFormat format,
const std::string& buffer, const std::string& msg);
+ float convertToApex(float val) {
+ return 2.0f * log2f(val);
+ }
+
// Destroys the buffer of APP1 segment if exists.
virtual void destroyApp1();
@@ -291,6 +230,8 @@
// The length of |app1_buffer_|.
unsigned int app1_length_;
+ // How precise the float-to-rational conversion for EXIF tags would be.
+ const static int kRationalPrecision = 10000;
};
#define SET_SHORT(ifd, tag, value) \
@@ -373,13 +314,11 @@
return true;
}
-bool ExifUtilsImpl::setAperture(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, numerator, denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setBrightness(int32_t numerator, int32_t denominator) {
- SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_BRIGHTNESS_VALUE, numerator, denominator);
+bool ExifUtilsImpl::setAperture(float aperture) {
+ float apexValue = convertToApex(aperture);
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE,
+ static_cast<uint32_t>(std::round(apexValue * kRationalPrecision)),
+ kRationalPrecision);
return true;
}
@@ -388,23 +327,6 @@
return true;
}
-bool ExifUtilsImpl::setComponentsConfiguration(
- const std::string& components_configuration) {
- SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_COMPONENTS_CONFIGURATION,
- EXIF_FORMAT_UNDEFINED, components_configuration);
- return true;
-}
-
-bool ExifUtilsImpl::setCompression(uint16_t compression) {
- SET_SHORT(EXIF_IFD_0, EXIF_TAG_COMPRESSION, compression);
- return true;
-}
-
-bool ExifUtilsImpl::setContrast(uint16_t contrast) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_CONTRAST, contrast);
- return true;
-}
-
bool ExifUtilsImpl::setDateTime(const struct tm& t) {
// The length is 20 bytes including NULL for termination in Exif standard.
char str[20];
@@ -421,53 +343,111 @@
return true;
}
-bool ExifUtilsImpl::setDescription(const std::string& description) {
- SET_STRING(EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_FORMAT_ASCII, description);
+bool ExifUtilsImpl::setDigitalZoomRatio(
+ uint32_t crop_width, uint32_t crop_height,
+ uint32_t sensor_width, uint32_t sensor_height) {
+ float zoomRatioX = (crop_width == 0) ? 1.0 : 1.0 * sensor_width / crop_width;
+ float zoomRatioY = (crop_height == 0) ? 1.0 : 1.0 * sensor_height / crop_height;
+ float zoomRatio = std::max(zoomRatioX, zoomRatioY);
+ const static float noZoomThreshold = 1.02f;
+
+ if (zoomRatio <= noZoomThreshold) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, 0, 1);
+ } else {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO,
+ static_cast<uint32_t>(std::round(zoomRatio * kRationalPrecision)),
+ kRationalPrecision);
+ }
return true;
}
-bool ExifUtilsImpl::setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, numerator, denominator);
+bool ExifUtilsImpl::setExposureMode(uint8_t exposure_mode) {
+ uint16_t exposureMode = (exposure_mode == ANDROID_CONTROL_AE_MODE_OFF) ? 1 : 0;
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposureMode);
return true;
}
-bool ExifUtilsImpl::setExposureBias(int32_t numerator, int32_t denominator) {
- SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, numerator, denominator);
+bool ExifUtilsImpl::setExposureTime(float exposure_time) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME,
+ static_cast<uint32_t>(std::round(exposure_time * kRationalPrecision)),
+ kRationalPrecision);
return true;
}
-bool ExifUtilsImpl::setExposureMode(uint16_t exposure_mode) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposure_mode);
- return true;
-}
+bool ExifUtilsImpl::setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode) {
+ // EXIF_TAG_FLASH bits layout per EXIF standard:
+ // Bit 0: 0 - did not fire
+ // 1 - fired
+ // Bit 1-2: status of return light
+ // Bit 3-4: 0 - unknown
+ // 1 - compulsory flash firing
+ // 2 - compulsory flash suppression
+ // 3 - auto mode
+ // Bit 5: 0 - flash function present
+ // 1 - no flash function
+ // Bit 6: 0 - no red-eye reduction mode or unknown
+ // 1 - red-eye reduction supported
+ uint16_t flash = 0x20;
-bool ExifUtilsImpl::setExposureProgram(uint16_t exposure_program) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, exposure_program);
- return true;
-}
+ if (flash_available == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
+ flash = 0x00;
-bool ExifUtilsImpl::setExposureTime(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, numerator, denominator);
- return true;
-}
+ if (flash_state == ANDROID_FLASH_STATE_FIRED) {
+ flash |= 0x1;
+ }
+ if (ae_mode == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
+ flash |= 0x40;
+ }
-bool ExifUtilsImpl::setFlash(uint16_t flash) {
+ uint16_t flashMode = 0;
+ switch (ae_mode) {
+ case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
+ case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
+ flashMode = 3; // AUTO
+ break;
+ case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
+ case ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH:
+ flashMode = 1; // ON
+ break;
+ case ANDROID_CONTROL_AE_MODE_OFF:
+ case ANDROID_CONTROL_AE_MODE_ON:
+ flashMode = 2; // OFF
+ break;
+ default:
+ flashMode = 0; // UNKNOWN
+ break;
+ }
+ flash |= (flashMode << 3);
+ }
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
return true;
}
-bool ExifUtilsImpl::setFNumber(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, numerator, denominator);
+bool ExifUtilsImpl::setFNumber(float f_number) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER,
+ static_cast<uint32_t>(std::round(f_number * kRationalPrecision)),
+ kRationalPrecision);
return true;
}
-bool ExifUtilsImpl::setFocalLength(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, denominator);
+bool ExifUtilsImpl::setFocalLength(float focal_length) {
+ uint32_t numerator = static_cast<uint32_t>(std::round(focal_length * kRationalPrecision));
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, kRationalPrecision);
return true;
}
-bool ExifUtilsImpl::setGainControl(uint16_t gain_control) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_GAIN_CONTROL, gain_control);
+bool ExifUtilsImpl::setFocalLengthIn35mmFilm(
+ float focal_length, float sensor_size_x, float sensor_size_y) {
+ static const float filmDiagonal = 43.27; // diagonal of 35mm film
+ static const float minSensorDiagonal = 0.01;
+ float sensorDiagonal = std::sqrt(
+ sensor_size_x * sensor_size_x + sensor_size_y * sensor_size_y);
+ sensorDiagonal = std::max(sensorDiagonal, minSensorDiagonal);
+ float focalLength35mmFilm = std::round(focal_length * filmDiagonal / sensorDiagonal);
+ focalLength35mmFilm = std::min(1.0f * 65535, focalLength35mmFilm);
+
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM,
+ static_cast<uint16_t>(focalLength35mmFilm));
return true;
}
@@ -614,18 +594,18 @@
return true;
}
-bool ExifUtilsImpl::setLightSource(uint16_t light_source) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_LIGHT_SOURCE, light_source);
+bool ExifUtilsImpl::setMaxAperture(float aperture) {
+ float maxAperture = convertToApex(aperture);
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE,
+ static_cast<uint32_t>(std::round(maxAperture * kRationalPrecision)),
+ kRationalPrecision);
return true;
}
-bool ExifUtilsImpl::setMaxAperture(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE, numerator, denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setMeteringMode(uint16_t metering_mode) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_METERING_MODE, metering_mode);
+bool ExifUtilsImpl::setExposureBias(int32_t ev,
+ uint32_t ev_step_numerator, uint32_t ev_step_denominator) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE,
+ ev * ev_step_numerator, ev_step_denominator);
return true;
}
@@ -658,33 +638,36 @@
return true;
}
-bool ExifUtilsImpl::setResolutionUnit(uint16_t resolution_unit) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_RESOLUTION_UNIT, resolution_unit);
+bool ExifUtilsImpl::setShutterSpeed(float exposure_time) {
+ float shutterSpeed = -log2f(exposure_time);
+ SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE,
+ static_cast<uint32_t>(shutterSpeed * kRationalPrecision), kRationalPrecision);
return true;
}
-bool ExifUtilsImpl::setSaturation(uint16_t saturation) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SATURATION, saturation);
- return true;
-}
+bool ExifUtilsImpl::setSubjectDistance(float diopters) {
+ const static float kInfinityDiopters = 1.0e-6;
+ uint32_t numerator, denominator;
+ uint16_t distanceRange;
+ if (diopters > kInfinityDiopters) {
+ float focusDistance = 1.0f / diopters;
+ numerator = static_cast<uint32_t>(std::round(focusDistance * kRationalPrecision));
+ denominator = kRationalPrecision;
-bool ExifUtilsImpl::setSceneCaptureType(uint16_t type) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, type);
- return true;
-}
-
-bool ExifUtilsImpl::setSharpness(uint16_t sharpness) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SHARPNESS, sharpness);
- return true;
-}
-
-bool ExifUtilsImpl::setShutterSpeed(int32_t numerator, int32_t denominator) {
- SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, numerator, denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setSubjectDistance(uint32_t numerator, uint32_t denominator) {
+ if (focusDistance < 1.0f) {
+ distanceRange = 1; // Macro
+ } else if (focusDistance < 3.0f) {
+ distanceRange = 2; // Close
+ } else {
+ distanceRange = 3; // Distant
+ }
+ } else {
+ numerator = 0xFFFFFFFF;
+ denominator = 1;
+ distanceRange = 3; // Distant
+ }
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE, numerator, denominator);
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE_RANGE, distanceRange);
return true;
}
@@ -695,23 +678,9 @@
return true;
}
-bool ExifUtilsImpl::setWhiteBalance(uint16_t white_balance) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, white_balance);
- return true;
-}
-
-bool ExifUtilsImpl::setXResolution(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_X_RESOLUTION, numerator, denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setYCbCrPositioning(uint16_t ycbcr_positioning) {
- SET_SHORT(EXIF_IFD_0, EXIF_TAG_YCBCR_POSITIONING, ycbcr_positioning);
- return true;
-}
-
-bool ExifUtilsImpl::setYResolution(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_Y_RESOLUTION, numerator, denominator);
+bool ExifUtilsImpl::setWhiteBalance(uint8_t white_balance) {
+ uint16_t whiteBalance = (white_balance == ANDROID_CONTROL_AWB_MODE_AUTO) ? 0 : 1;
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, whiteBalance);
return true;
}
@@ -748,16 +717,6 @@
return true;
}
-bool ExifUtilsImpl::setMake(const std::string& make) {
- SET_STRING(EXIF_IFD_0, EXIF_TAG_MAKE, EXIF_FORMAT_ASCII, make);
- return true;
-}
-
-bool ExifUtilsImpl::setModel(const std::string& model) {
- SET_STRING(EXIF_IFD_0, EXIF_TAG_MODEL, EXIF_FORMAT_ASCII, model);
- return true;
-}
-
void ExifUtilsImpl::reset() {
destroyApp1();
if (exif_data_) {
@@ -898,9 +857,8 @@
}
bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
+ const CameraMetadata& staticInfo,
const size_t imageWidth, const size_t imageHeight) {
- // How precise the float-to-rational conversion for EXIF tags would be.
- constexpr int kRationalPrecision = 10000;
if (!setImageWidth(imageWidth) ||
!setImageHeight(imageHeight)) {
ALOGE("%s: setting image resolution failed.", __FUNCTION__);
@@ -921,15 +879,37 @@
if (entry.count) {
focal_length = entry.data.f[0];
- if (!setFocalLength(
- static_cast<uint32_t>(focal_length * kRationalPrecision), kRationalPrecision)) {
+ if (!setFocalLength(focal_length)) {
ALOGE("%s: setting focal length failed.", __FUNCTION__);
return false;
}
+
+ camera_metadata_ro_entry sensorSizeEntry =
+ staticInfo.find(ANDROID_SENSOR_INFO_PHYSICAL_SIZE);
+ if (sensorSizeEntry.count == 2) {
+ if (!setFocalLengthIn35mmFilm(
+ focal_length, sensorSizeEntry.data.f[0], sensorSizeEntry.data.f[1])) {
+ ALOGE("%s: setting focal length in 35mm failed.", __FUNCTION__);
+ return false;
+ }
+ }
} else {
ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
}
+ if (metadata.exists(ANDROID_SCALER_CROP_REGION) &&
+ staticInfo.exists(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE)) {
+ entry = metadata.find(ANDROID_SCALER_CROP_REGION);
+ camera_metadata_ro_entry activeArrayEntry =
+ staticInfo.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+
+ if (!setDigitalZoomRatio(entry.data.i32[2], entry.data.i32[3],
+ activeArrayEntry.data.i32[2], activeArrayEntry.data.i32[3])) {
+ ALOGE("%s: setting digital zoom ratio failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
if (entry.count < 3) {
@@ -973,6 +953,18 @@
}
}
+ if (staticInfo.exists(ANDROID_CONTROL_AE_COMPENSATION_STEP) &&
+ metadata.exists(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION)) {
+ entry = metadata.find(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION);
+ camera_metadata_ro_entry stepEntry =
+ staticInfo.find(ANDROID_CONTROL_AE_COMPENSATION_STEP);
+ if (!setExposureBias(entry.data.i32[0], stepEntry.data.r[0].numerator,
+ stepEntry.data.r[0].denominator)) {
+ ALOGE("%s: setting exposure bias failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
if (metadata.exists(ANDROID_JPEG_ORIENTATION)) {
entry = metadata.find(ANDROID_JPEG_ORIENTATION);
if (!setOrientation(entry.data.i32[0])) {
@@ -983,50 +975,97 @@
if (metadata.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
entry = metadata.find(ANDROID_SENSOR_EXPOSURE_TIME);
- // int64_t of nanoseconds
- if (!setExposureTime(entry.data.i64[0],1000000000u)) {
+ float exposure_time = 1.0f * entry.data.i64[0] / 1e9;
+ if (!setExposureTime(exposure_time)) {
ALOGE("%s: setting exposure time failed.", __FUNCTION__);
return false;
}
+
+ if (!setShutterSpeed(exposure_time)) {
+ ALOGE("%s: setting shutter speed failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ if (metadata.exists(ANDROID_LENS_FOCUS_DISTANCE)) {
+ entry = metadata.find(ANDROID_LENS_FOCUS_DISTANCE);
+ if (!setSubjectDistance(entry.data.f[0])) {
+ ALOGE("%s: setting subject distance failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ if (metadata.exists(ANDROID_SENSOR_SENSITIVITY)) {
+ entry = metadata.find(ANDROID_SENSOR_SENSITIVITY);
+ int32_t iso = entry.data.i32[0];
+ camera_metadata_ro_entry postRawSensEntry =
+ metadata.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
+ if (postRawSensEntry.count > 0) {
+ iso = iso * postRawSensEntry.data.i32[0] / 100;
+ }
+
+ if (!setIsoSpeedRating(static_cast<uint16_t>(iso))) {
+ ALOGE("%s: setting iso rating failed.", __FUNCTION__);
+ return false;
+ }
}
if (metadata.exists(ANDROID_LENS_APERTURE)) {
- const int kAperturePrecision = 10000;
entry = metadata.find(ANDROID_LENS_APERTURE);
- if (!setFNumber(entry.data.f[0] * kAperturePrecision, kAperturePrecision)) {
+ if (!setFNumber(entry.data.f[0])) {
ALOGE("%s: setting F number failed.", __FUNCTION__);
return false;
}
+ if (!setAperture(entry.data.f[0])) {
+ ALOGE("%s: setting aperture failed.", __FUNCTION__);
+ return false;
+ }
}
- if (metadata.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
- entry = metadata.find(ANDROID_FLASH_INFO_AVAILABLE);
- if (entry.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_FALSE) {
- const uint32_t kNoFlashFunction = 0x20;
- if (!setFlash(kNoFlashFunction)) {
- ALOGE("%s: setting flash failed.", __FUNCTION__);
- return false;
- }
- } else {
- ALOGE("%s: Unsupported flash info: %d",__FUNCTION__, entry.data.u8[0]);
+ static const uint16_t kSRGBColorSpace = 1;
+ if (!setColorSpace(kSRGBColorSpace)) {
+ ALOGE("%s: setting color space failed.", __FUNCTION__);
+ return false;
+ }
+
+ if (staticInfo.exists(ANDROID_LENS_INFO_AVAILABLE_APERTURES)) {
+ entry = staticInfo.find(ANDROID_LENS_INFO_AVAILABLE_APERTURES);
+ if (!setMaxAperture(entry.data.f[0])) {
+ ALOGE("%s: setting max aperture failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ if (staticInfo.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
+ entry = staticInfo.find(ANDROID_FLASH_INFO_AVAILABLE);
+ camera_metadata_ro_entry flashStateEntry = metadata.find(ANDROID_FLASH_STATE);
+ camera_metadata_ro_entry aeModeEntry = metadata.find(ANDROID_CONTROL_AE_MODE);
+ uint8_t flashState = flashStateEntry.count > 0 ?
+ flashStateEntry.data.u8[0] : ANDROID_FLASH_STATE_UNAVAILABLE;
+ uint8_t aeMode = aeModeEntry.count > 0 ?
+ aeModeEntry.data.u8[0] : ANDROID_CONTROL_AE_MODE_OFF;
+
+ if (!setFlash(entry.data.u8[0], flashState, aeMode)) {
+ ALOGE("%s: setting flash failed.", __FUNCTION__);
return false;
}
}
if (metadata.exists(ANDROID_CONTROL_AWB_MODE)) {
entry = metadata.find(ANDROID_CONTROL_AWB_MODE);
- if (entry.data.u8[0] == ANDROID_CONTROL_AWB_MODE_AUTO) {
- const uint16_t kAutoWhiteBalance = 0;
- if (!setWhiteBalance(kAutoWhiteBalance)) {
- ALOGE("%s: setting white balance failed.", __FUNCTION__);
- return false;
- }
- } else {
- ALOGE("%s: Unsupported awb mode: %d", __FUNCTION__, entry.data.u8[0]);
+ if (!setWhiteBalance(entry.data.u8[0])) {
+ ALOGE("%s: setting white balance failed.", __FUNCTION__);
return false;
}
}
+ if (metadata.exists(ANDROID_CONTROL_AE_MODE)) {
+ entry = metadata.find(ANDROID_CONTROL_AE_MODE);
+ if (!setExposureMode(entry.data.u8[0])) {
+ ALOGE("%s: setting exposure mode failed.", __FUNCTION__);
+ return false;
+ }
+ }
if (time_available) {
char str[4];
if (snprintf(str, sizeof(str), "%03ld", tp.tv_nsec / 1000000) < 0) {
diff --git a/services/camera/libcameraservice/utils/ExifUtils.h b/services/camera/libcameraservice/utils/ExifUtils.h
index 8ccdd8f..c78bab9 100644
--- a/services/camera/libcameraservice/utils/ExifUtils.h
+++ b/services/camera/libcameraservice/utils/ExifUtils.h
@@ -52,78 +52,57 @@
// Set all known fields from a metadata structure
virtual bool setFromMetadata(const CameraMetadata& metadata,
+ const CameraMetadata& staticInfo,
const size_t imageWidth, const size_t imageHeight) = 0;
// Sets the len aperture.
// Returns false if memory allocation fails.
- virtual bool setAperture(uint32_t numerator, uint32_t denominator) = 0;
+ virtual bool setAperture(float aperture) = 0;
- // Sets the value of brightness.
- // Returns false if memory allocation fails.
- virtual bool setBrightness(int32_t numerator, int32_t denominator) = 0;
-
- // Sets the color space.
+ // sets the color space.
// Returns false if memory allocation fails.
virtual bool setColorSpace(uint16_t color_space) = 0;
- // Sets the information to compressed data.
- // Returns false if memory allocation fails.
- virtual bool setComponentsConfiguration(const std::string& components_configuration) = 0;
-
- // Sets the compression scheme used for the image data.
- // Returns false if memory allocation fails.
- virtual bool setCompression(uint16_t compression) = 0;
-
- // Sets image contrast.
- // Returns false if memory allocation fails.
- virtual bool setContrast(uint16_t contrast) = 0;
-
// Sets the date and time of image last modified. It takes local time. The
// name of the tag is DateTime in IFD0.
// Returns false if memory allocation fails.
virtual bool setDateTime(const struct tm& t) = 0;
- // Sets the image description.
- // Returns false if memory allocation fails.
- virtual bool setDescription(const std::string& description) = 0;
-
// Sets the digital zoom ratio. If the numerator is 0, it means digital zoom
// was not used.
// Returns false if memory allocation fails.
- virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) = 0;
+ virtual bool setDigitalZoomRatio(uint32_t crop_width, uint32_t crop_height,
+ uint32_t sensor_width, uint32_t sensor_height) = 0;
// Sets the exposure bias.
// Returns false if memory allocation fails.
- virtual bool setExposureBias(int32_t numerator, int32_t denominator) = 0;
+ virtual bool setExposureBias(int32_t ev,
+ uint32_t ev_step_numerator, uint32_t ev_step_denominator) = 0;
// Sets the exposure mode set when the image was shot.
// Returns false if memory allocation fails.
- virtual bool setExposureMode(uint16_t exposure_mode) = 0;
-
- // Sets the program used by the camera to set exposure when the picture is
- // taken.
- // Returns false if memory allocation fails.
- virtual bool setExposureProgram(uint16_t exposure_program) = 0;
+ virtual bool setExposureMode(uint8_t exposure_mode) = 0;
// Sets the exposure time, given in seconds.
// Returns false if memory allocation fails.
- virtual bool setExposureTime(uint32_t numerator, uint32_t denominator) = 0;
+ virtual bool setExposureTime(float exposure_time) = 0;
// Sets the status of flash.
// Returns false if memory allocation fails.
- virtual bool setFlash(uint16_t flash) = 0;
+ virtual bool setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode) = 0;
// Sets the F number.
// Returns false if memory allocation fails.
- virtual bool setFNumber(uint32_t numerator, uint32_t denominator) = 0;
+ virtual bool setFNumber(float f_number) = 0;
// Sets the focal length of lens used to take the image in millimeters.
// Returns false if memory allocation fails.
- virtual bool setFocalLength(uint32_t numerator, uint32_t denominator) = 0;
+ virtual bool setFocalLength(float focal_length) = 0;
- // Sets the degree of overall image gain adjustment.
+ // Sets the focal length of lens for 35mm film used to take the image in millimeters.
// Returns false if memory allocation fails.
- virtual bool setGainControl(uint16_t gain_control) = 0;
+ virtual bool setFocalLengthIn35mmFilm(float focal_length,
+ float sensor_size_x, float sensor_size_y) = 0;
// Sets the altitude in meters.
// Returns false if memory allocation fails.
@@ -157,45 +136,21 @@
// Returns false if memory allocation fails.
virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings) = 0;
- // Sets the kind of light source.
- // Returns false if memory allocation fails.
- virtual bool setLightSource(uint16_t light_source) = 0;
-
// Sets the smallest F number of the lens.
// Returns false if memory allocation fails.
- virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the metering mode.
- // Returns false if memory allocation fails.
- virtual bool setMeteringMode(uint16_t metering_mode) = 0;
+ virtual bool setMaxAperture(float aperture) = 0;
// Sets image orientation.
// Returns false if memory allocation fails.
virtual bool setOrientation(uint16_t orientation) = 0;
- // Sets the unit for measuring XResolution and YResolution.
- // Returns false if memory allocation fails.
- virtual bool setResolutionUnit(uint16_t resolution_unit) = 0;
-
- // Sets image saturation.
- // Returns false if memory allocation fails.
- virtual bool setSaturation(uint16_t saturation) = 0;
-
- // Sets the type of scene that was shot.
- // Returns false if memory allocation fails.
- virtual bool setSceneCaptureType(uint16_t type) = 0;
-
- // Sets image sharpness.
- // Returns false if memory allocation fails.
- virtual bool setSharpness(uint16_t sharpness) = 0;
-
// Sets the shutter speed.
// Returns false if memory allocation fails.
- virtual bool setShutterSpeed(int32_t numerator, int32_t denominator) = 0;
+ virtual bool setShutterSpeed(float exposure_time) = 0;
// Sets the distance to the subject, given in meters.
// Returns false if memory allocation fails.
- virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator) = 0;
+ virtual bool setSubjectDistance(float diopters) = 0;
// Sets the fractions of seconds for the <DateTime> tag.
// Returns false if memory allocation fails.
@@ -203,28 +158,7 @@
// Sets the white balance mode set when the image was shot.
// Returns false if memory allocation fails.
- virtual bool setWhiteBalance(uint16_t white_balance) = 0;
-
- // Sets the number of pixels per resolution unit in the image width.
- // Returns false if memory allocation fails.
- virtual bool setXResolution(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the position of chrominance components in relation to the luminance
- // component.
- // Returns false if memory allocation fails.
- virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning) = 0;
-
- // Sets the number of pixels per resolution unit in the image length.
- // Returns false if memory allocation fails.
- virtual bool setYResolution(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the manufacturer of camera.
- // Returns false if memory allocation fails.
- virtual bool setMake(const std::string& make) = 0;
-
- // Sets the model number of camera.
- // Returns false if memory allocation fails.
- virtual bool setModel(const std::string& model) = 0;
+ virtual bool setWhiteBalance(uint8_t white_blanace) = 0;
// Generates APP1 segment.
// Returns false if generating APP1 segment fails.
diff --git a/services/mediacodec/seccomp_policy/mediacodec-arm.policy b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
index 9bdd4c8..3870a11 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
@@ -58,8 +58,4 @@
getdents64: 1
getrandom: 1
-# Used by UBSan diagnostic messages
-readlink: 1
-open: 1
-
@include /system/etc/seccomp_policy/crash_dump.arm.policy
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86.policy b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
index a1ef16f..845f84b 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
@@ -67,8 +67,4 @@
getpid: 1
gettid: 1
-# Used by UBSan diagnostic messages
-readlink: 1
-open: 1
-
@include /system/etc/seccomp_policy/crash_dump.x86.policy