Merge "bufferpool2.0 tests: add read/write verification"
diff --git a/media/libstagefright/bqhelper/Conversion.cpp b/media/libstagefright/bqhelper/Conversion.cpp
index ffed005..91d7c74 100644
--- a/media/libstagefright/bqhelper/Conversion.cpp
+++ b/media/libstagefright/bqhelper/Conversion.cpp
@@ -98,6 +98,17 @@
*/
/**
+ * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
+ *
+ * \param[in] t The source `Return<void>`.
+ * \return The corresponding `status_t`.
+ */
+// convert: Return<void> -> status_t
+status_t toStatusT(Return<void> const& t) {
+ return t.isOk() ? OK : (t.isDeadObject() ? DEAD_OBJECT : UNKNOWN_ERROR);
+}
+
+/**
* \brief Convert `Return<void>` to `binder::Status`.
*
* \param[in] t The source `Return<void>`.
@@ -107,22 +118,11 @@
::android::binder::Status toBinderStatus(
Return<void> const& t) {
return ::android::binder::Status::fromExceptionCode(
- t.isOk() ? OK : UNKNOWN_ERROR,
+ toStatusT(t),
t.description().c_str());
}
/**
- * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
- *
- * \param[in] t The source `Return<void>`.
- * \return The corresponding `status_t`.
- */
-// convert: Return<void> -> status_t
-status_t toStatusT(Return<void> const& t) {
- return t.isOk() ? OK : UNKNOWN_ERROR;
-}
-
-/**
* \brief Wrap `native_handle_t*` in `hidl_handle`.
*
* \param[in] nh The source `native_handle_t*`.
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
index a9fce55..0f229f7 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
@@ -190,7 +190,12 @@
*/
// convert: Status -> status_t
inline status_t toStatusT(Return<Status> const& t) {
- return t.isOk() ? toStatusT(static_cast<Status>(t)) : UNKNOWN_ERROR;
+ if (t.isOk()) {
+ return toStatusT(static_cast<Status>(t));
+ } else if (t.isDeadObject()) {
+ return DEAD_OBJECT;
+ }
+ return UNKNOWN_ERROR;
}
/**
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index 8c1ac59..c66cd50 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -84,8 +84,17 @@
EXPORT
media_status_t AMediaExtractor_setDataSource(AMediaExtractor *mData, const char *location) {
- ALOGV("setDataSource(%s)", location);
- // TODO: add header support
+ return AMediaExtractor_setDataSourceWithHeaders(mData, location, 0, NULL, NULL);
+}
+
+EXPORT
+media_status_t AMediaExtractor_setDataSourceWithHeaders(AMediaExtractor *mData,
+ const char *uri,
+ int numheaders,
+ const char * const *keys,
+ const char * const *values) {
+
+ ALOGV("setDataSource(%s)", uri);
JNIEnv *env = AndroidRuntime::getJNIEnv();
jobject service = NULL;
@@ -109,7 +118,7 @@
return AMEDIA_ERROR_UNSUPPORTED;
}
- jstring jloc = env->NewStringUTF(location);
+ jstring jloc = env->NewStringUTF(uri);
service = env->CallStaticObjectMethod(mediahttpclass, mediaHttpCreateMethod, jloc);
env->DeleteLocalRef(jloc);
@@ -120,7 +129,15 @@
httpService = interface_cast<IMediaHTTPService>(binder);
}
- status_t err = mData->mImpl->setDataSource(httpService, location, NULL);
+ KeyedVector<String8, String8> headers;
+ for (int i = 0; i < numheaders; ++i) {
+ String8 key8(keys[i]);
+ String8 value8(values[i]);
+ headers.add(key8, value8);
+ }
+
+ status_t err;
+ err = mData->mImpl->setDataSource(httpService, uri, numheaders > 0 ? &headers : NULL);
env->ExceptionClear();
return translate_error(err);
}
diff --git a/media/ndk/include/media/NdkMediaExtractor.h b/media/ndk/include/media/NdkMediaExtractor.h
index 6a1796f..413bc1a 100644
--- a/media/ndk/include/media/NdkMediaExtractor.h
+++ b/media/ndk/include/media/NdkMediaExtractor.h
@@ -72,7 +72,27 @@
*/
media_status_t AMediaExtractor_setDataSource(AMediaExtractor*,
const char *location) __INTRODUCED_IN(21);
- // TODO support headers
+
+#if __ANDROID_API__ >= 29
+/**
+ * Set the |uri| from which the extractor will read,
+ * plus additional http headers when initiating the request.
+ *
+ * Headers will contain corresponding items from |keys| & |values|
+ * from indices 0 (inclusive) to numheaders-1 (inclusive):
+ *
+ * keys[0]:values[0]
+ * ...
+ * keys[numheaders - 1]:values[numheaders - 1]
+ *
+ */
+media_status_t AMediaExtractor_setDataSourceWithHeaders(AMediaExtractor*,
+ const char *uri,
+ int numheaders,
+ const char * const *keys,
+ const char * const *values) __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
#if __ANDROID_API__ >= 28
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index 0751a55..1fd69a2 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -184,6 +184,7 @@
AMediaExtractor_setDataSource;
AMediaExtractor_setDataSourceCustom; # introduced=28
AMediaExtractor_setDataSourceFd;
+ AMediaExtractor_setDataSourceWithHeaders; # introduced=29
AMediaExtractor_unselectTrack;
AMediaFormat_clear; # introduced=29
AMediaFormat_copy; # introduced=29
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index c4c742e..6cab441 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1157,7 +1157,8 @@
{
sp<ThreadBase> thread = mThread.promote();
if (thread != 0 &&
- (thread->type() == ThreadBase::OFFLOAD || thread->type() == ThreadBase::DIRECT)) {
+ (thread->type() == ThreadBase::OFFLOAD || thread->type() == ThreadBase::DIRECT) &&
+ !isNonOffloadableEnabled_l()) {
PlaybackThread *t = (PlaybackThread *)thread.get();
float vol_l = (float)left / (1 << 24);
float vol_r = (float)right / (1 << 24);
@@ -2552,6 +2553,11 @@
bool AudioFlinger::EffectChain::isNonOffloadableEnabled()
{
Mutex::Autolock _l(mLock);
+ return isNonOffloadableEnabled_l();
+}
+
+bool AudioFlinger::EffectChain::isNonOffloadableEnabled_l()
+{
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
if (mEffects[i]->isEnabled() && !mEffects[i]->isOffloadable()) {
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index e04ee8e..15a26ea 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -378,6 +378,7 @@
// At least one non offloadable effect in the chain is enabled
bool isNonOffloadableEnabled();
+ bool isNonOffloadableEnabled_l();
void syncHalEffectsState();
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 2a8b397..e4f3cf1 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2811,12 +2811,9 @@
}
// Check if offload has been disabled
- char propValue[PROPERTY_VALUE_MAX];
- if (property_get("audio.offload.disable", propValue, "0")) {
- if (atoi(propValue) != 0) {
- ALOGV("offload disabled by audio.offload.disable=%s", propValue );
- return false;
- }
+ if (property_get_bool("audio.offload.disable", false /* default_value */)) {
+ ALOGV("offload disabled by audio.offload.disable");
+ return false;
}
// Check if stream type is music, then only allow offload as of now.
@@ -2835,9 +2832,12 @@
}
//If duration is less than minimum value defined in property, return false
- if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
- if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
- ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
+ const int min_duration_secs = property_get_int32(
+ "audio.offload.min.duration.secs", -1 /* default_value */);
+ if (min_duration_secs >= 0) {
+ if (offloadInfo.duration_us < min_duration_secs * 1000000LL) {
+ ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%d)",
+ min_duration_secs);
return false;
}
} else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 8476711..ecbcf76 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -237,12 +237,14 @@
/**
* Return buffer back to ANativeWindow
*/
- if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR || mDropBuffers) {
+ if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR || mDropBuffers || timestamp == 0) {
// Cancel buffer
if (mDropBuffers) {
ALOGV("%s: Dropping a frame for stream %d.", __FUNCTION__, mId);
- } else {
+ } else if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
ALOGW("%s: A frame is dropped for stream %d due to buffer error.", __FUNCTION__, mId);
+ } else {
+ ALOGE("%s: Stream %d: timestamp shouldn't be 0", __FUNCTION__, mId);
}
res = currentConsumer->cancelBuffer(currentConsumer.get(),
@@ -268,10 +270,6 @@
mTraceFirstBuffer = false;
}
- if (timestamp == 0) {
- ALOGW("%s: Stream %d: timestamp shouldn't be 0", __FUNCTION__, mId);
- }
-
/* Certain consumers (such as AudioSource or HardwareComposer) use
* MONOTONIC time, causing time misalignment if camera timestamp is
* in BOOTTIME. Do the conversion if necessary. */
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index b208d9f..9238590 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -662,9 +662,12 @@
removeOutstandingBuffer(buffer);
+ // Buffer status may be changed, so make a copy of the stream_buffer struct.
+ camera3_stream_buffer b = buffer;
if (timestampIncreasing && timestamp != 0 && timestamp <= mLastTimestamp) {
- ALOGW("%s: Stream %d: timestamp %" PRId64 " is not increasing. Prev timestamp %" PRId64,
+ ALOGE("%s: Stream %d: timestamp %" PRId64 " is not increasing. Prev timestamp %" PRId64,
__FUNCTION__, mId, timestamp, mLastTimestamp);
+ b.status = CAMERA3_BUFFER_STATUS_ERROR;
}
mLastTimestamp = timestamp;
@@ -676,9 +679,9 @@
*
* Do this for getBuffer as well.
*/
- status_t res = returnBufferLocked(buffer, timestamp);
+ status_t res = returnBufferLocked(b, timestamp);
if (res == OK) {
- fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true);
+ fireBufferListenersLocked(b, /*acquired*/false, /*output*/true);
}
// Even if returning the buffer failed, we still want to signal whoever is waiting for the