summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camera/Android.bp32
-rw-r--r--camera/CameraParameters.cpp3
-rw-r--r--camera/ICameraClient.cpp15
-rw-r--r--camera/cameraserver/Android.mk10
-rw-r--r--camera/include/camera/CameraMetadata.h1
-rw-r--r--camera/include/camera/CameraParameters2.h2
-rw-r--r--camera/parameters.go52
l---------include/media/AudioSession.h1
-rw-r--r--media/libaudioclient/AudioSystem.cpp39
-rw-r--r--media/libaudioclient/IAudioPolicyService.cpp43
-rw-r--r--media/libaudioclient/IAudioPolicyServiceClient.cpp30
-rw-r--r--media/libaudioclient/include/media/AudioPolicy.h2
-rw-r--r--media/libaudioclient/include/media/AudioSession.h71
-rw-r--r--media/libaudioclient/include/media/AudioSystem.h8
-rw-r--r--media/libaudioclient/include/media/IAudioPolicyService.h3
-rw-r--r--media/libaudioclient/include/media/IAudioPolicyServiceClient.h3
-rw-r--r--media/libmedia/omx/1.0/WOmxNode.cpp3
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp5
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp3
-rw-r--r--media/libstagefright/ACodec.cpp1
-rw-r--r--media/libstagefright/CameraSource.cpp18
-rw-r--r--media/libstagefright/CameraSourceTimeLapse.cpp9
-rw-r--r--media/libstagefright/FLACExtractor.cpp2
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp9
-rw-r--r--media/libstagefright/MediaCodecSource.cpp4
-rw-r--r--media/libstagefright/StagefrightMediaScanner.cpp8
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp7
-rw-r--r--media/libstagefright/SurfaceMediaSource.cpp4
-rw-r--r--media/libstagefright/SurfaceUtils.cpp7
-rw-r--r--media/libstagefright/matroska/MatroskaExtractor.cpp38
-rw-r--r--media/libstagefright/omx/1.0/WOmxNode.cpp3
-rw-r--r--media/libstagefright/omx/Android.bp11
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.cpp2
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp6
-rw-r--r--media/mediaserver/Android.mk11
-rw-r--r--media/mediaserver/main_mediaserver.cpp12
-rw-r--r--media/mtp/MtpFfsHandle.cpp2
-rw-r--r--media/mtp/MtpServer.cpp4
-rw-r--r--media/ndk/NdkMediaCodec.cpp7
-rw-r--r--media/ndk/include/media/NdkMediaCodec.h6
-rw-r--r--services/audioflinger/AudioFlinger.cpp3
-rw-r--r--services/audioflinger/Effects.cpp4
-rw-r--r--services/audiopolicy/AudioPolicyInterface.h2
-rw-r--r--services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h2
-rw-r--r--services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp4
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.cpp2
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.h10
-rw-r--r--services/audiopolicy/service/AudioPolicyClientImpl.cpp7
-rw-r--r--services/audiopolicy/service/AudioPolicyEffects.cpp116
-rw-r--r--services/audiopolicy/service/AudioPolicyEffects.h21
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp66
-rw-r--r--services/audiopolicy/service/AudioPolicyService.cpp54
-rw-r--r--services/audiopolicy/service/AudioPolicyService.h22
-rw-r--r--services/camera/libcameraservice/Android.mk10
-rw-r--r--services/camera/libcameraservice/CameraService.cpp6
-rw-r--r--services/camera/libcameraservice/api1/Camera2Client.cpp6
-rw-r--r--services/camera/libcameraservice/api1/CameraClient.cpp36
-rw-r--r--services/camera/libcameraservice/api1/CameraClient.h3
-rw-r--r--services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp6
-rw-r--r--services/camera/libcameraservice/common/CameraDeviceBase.h5
-rw-r--r--services/camera/libcameraservice/device1/CameraHardwareInterface.cpp37
-rw-r--r--services/camera/libcameraservice/device1/CameraHardwareInterface.h13
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp14
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.h6
-rw-r--r--services/camera/libcameraservice/device3/Camera3DummyStream.cpp4
-rw-r--r--services/camera/libcameraservice/device3/Camera3DummyStream.h6
-rw-r--r--services/camera/libcameraservice/device3/Camera3OutputStream.cpp19
-rw-r--r--services/camera/libcameraservice/device3/Camera3OutputStream.h8
-rw-r--r--services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h5
-rw-r--r--services/soundtrigger/SoundTriggerHwService.cpp31
70 files changed, 950 insertions, 75 deletions
diff --git a/camera/Android.bp b/camera/Android.bp
index c76ae507fd..58cc622c3f 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -14,6 +14,26 @@
subdirs = ["ndk"]
+bootstrap_go_package {
+ name: "soong-camera-parameters",
+ pkgPath: "android/soong/camera_parameters",
+ deps: [
+ "blueprint",
+ "blueprint-pathtools",
+ "soong",
+ "soong-android",
+ "soong-cc",
+ ],
+ srcs: [
+ "parameters.go",
+ ],
+ pluginFor: ["soong_build"],
+}
+
+camera_parameters_defaults {
+ name: "camera_parameters_defaults",
+}
+
cc_library_shared {
name: "libcamera_client",
@@ -39,7 +59,6 @@ cc_library_shared {
// Source for camera interface parcelables, and manually-written interfaces
"Camera.cpp",
"CameraMetadata.cpp",
- "CameraParameters.cpp",
"CaptureResult.cpp",
"CameraParameters2.cpp",
"ICamera.cpp",
@@ -54,6 +73,17 @@ cc_library_shared {
"VendorTagDescriptor.cpp",
],
+ product_variables: {
+ lineage: {
+ uses_generic_camera_parameter_library: {
+ srcs: [
+ "CameraParameters.cpp",
+ ],
+ },
+ },
+ },
+ defaults: ["camera_parameters_defaults"],
+
shared_libs: [
"libcutils",
"libutils",
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index 68969cf649..de8ac2ffce 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -237,6 +237,9 @@ void CameraParameters::unflatten(const String8 &params)
void CameraParameters::set(const char *key, const char *value)
{
+ if (key == NULL || value == NULL)
+ return;
+
// XXX i think i can do this with strspn()
if (strchr(key, '=') || strchr(key, ';')) {
//XXX ALOGE("Key \"%s\"contains invalid character (= or ;)", key);
diff --git a/camera/ICameraClient.cpp b/camera/ICameraClient.cpp
index 8620f36022..d07a8d5f37 100644
--- a/camera/ICameraClient.cpp
+++ b/camera/ICameraClient.cpp
@@ -51,7 +51,11 @@ public:
data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
data.writeInt32(msgType);
data.writeInt32(ext1);
- data.writeInt32(ext2);
+ if ((msgType == CAMERA_MSG_PREVIEW_FRAME) && (ext1 == CAMERA_FRAME_DATA_FD)) {
+ data.writeFileDescriptor(ext2);
+ } else {
+ data.writeInt32(ext2);
+ }
remote()->transact(NOTIFY_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
}
@@ -129,8 +133,13 @@ status_t BnCameraClient::onTransact(
ALOGV("NOTIFY_CALLBACK");
CHECK_INTERFACE(ICameraClient, data, reply);
int32_t msgType = data.readInt32();
- int32_t ext1 = data.readInt32();
- int32_t ext2 = data.readInt32();
+ int32_t ext1 = data.readInt32();
+ int32_t ext2 = 0;
+ if ((msgType == CAMERA_MSG_PREVIEW_FRAME) && (ext1 == CAMERA_FRAME_DATA_FD)) {
+ ext2 = data.readFileDescriptor();
+ } else {
+ ext2 = data.readInt32();
+ }
notifyCallback(msgType, ext1, ext2);
return NO_ERROR;
} break;
diff --git a/camera/cameraserver/Android.mk b/camera/cameraserver/Android.mk
index b8c94e64e3..b41656f01d 100644
--- a/camera/cameraserver/Android.mk
+++ b/camera/cameraserver/Android.mk
@@ -14,6 +14,9 @@
LOCAL_PATH:= $(call my-dir)
+ifeq ($(TARGET_HAS_LEGACY_CAMERA_HAL1),true)
+$(warning Target has integrated cameraserver into mediaserver. This is weakening security measures introduced in 7.0)
+else
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
@@ -32,6 +35,12 @@ LOCAL_SHARED_LIBRARIES := \
android.hardware.camera.device@1.0 \
android.hardware.camera.device@3.2
+ifeq ($(TARGET_USES_QTI_CAMERA_DEVICE), true)
+LOCAL_CFLAGS += -DQTI_CAMERA_DEVICE
+LOCAL_SHARED_LIBRARIES += \
+ vendor.qti.hardware.camera.device@1.0
+endif
+
LOCAL_MODULE:= cameraserver
LOCAL_32_BIT_ONLY := true
@@ -40,3 +49,4 @@ LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter
LOCAL_INIT_RC := cameraserver.rc
include $(BUILD_EXECUTABLE)
+endif
diff --git a/camera/include/camera/CameraMetadata.h b/camera/include/camera/CameraMetadata.h
index d28447784f..e2b743db54 100644
--- a/camera/include/camera/CameraMetadata.h
+++ b/camera/include/camera/CameraMetadata.h
@@ -222,6 +222,7 @@ class CameraMetadata: public Parcelable {
private:
camera_metadata_t *mBuffer;
+ volatile char mReserved[3] __attribute__ ((unused));
mutable bool mLocked;
/**
diff --git a/camera/include/camera/CameraParameters2.h b/camera/include/camera/CameraParameters2.h
index f691cd6ea0..5fae079376 100644
--- a/camera/include/camera/CameraParameters2.h
+++ b/camera/include/camera/CameraParameters2.h
@@ -19,7 +19,7 @@
#include <utils/Vector.h>
#include <utils/String8.h>
-#include "CameraParameters.h"
+#include <camera/CameraParameters.h>
namespace android {
diff --git a/camera/parameters.go b/camera/parameters.go
new file mode 100644
index 0000000000..dfaa278190
--- /dev/null
+++ b/camera/parameters.go
@@ -0,0 +1,52 @@
+// Copyright (C) 2017 The LineageOS Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package lineage
+
+import (
+ "android/soong/android"
+ "android/soong/cc"
+)
+
+func init() {
+ android.RegisterModuleType("camera_parameters_defaults", cameraParametersFactory)
+}
+
+func cameraParametersFactory() android.Module {
+ module := cc.DefaultsFactory()
+ android.AddLoadHook(module, cameraParameters)
+
+ return module
+}
+
+func cameraParameters(ctx android.LoadHookContext) {
+ type props struct {
+ Whole_static_libs []string
+ }
+
+ p := &props{}
+ p.Whole_static_libs = globalDefaults(ctx)
+
+ ctx.AppendProperties(p)
+}
+
+func globalDefaults(ctx android.BaseContext) []string {
+ var staticLibs []string
+
+ device_camera_parameters_lib := ctx.DeviceConfig().SpecificCameraParametersLibrary()
+ if len(device_camera_parameters_lib) > 0 {
+ staticLibs = append(staticLibs, device_camera_parameters_lib)
+ }
+
+ return staticLibs
+}
diff --git a/include/media/AudioSession.h b/include/media/AudioSession.h
new file mode 120000
index 0000000000..005e48e7ed
--- /dev/null
+++ b/include/media/AudioSession.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioSession.h \ No newline at end of file
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index cdc75ace66..19b377fa8f 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -39,7 +39,7 @@ sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
audio_error_callback AudioSystem::gAudioErrorCallback = NULL;
dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
record_config_callback AudioSystem::gRecordConfigCallback = NULL;
-
+audio_session_callback AudioSystem::gAudioSessionCallback = NULL;
// establish binder interface to AudioFlinger service
const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
@@ -706,6 +706,17 @@ status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback(
gRecordConfigCallback = cb;
}
+/*static*/ status_t AudioSystem::setAudioSessionCallback(audio_session_callback cb)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+
+ Mutex::Autolock _l(gLock);
+ gAudioSessionCallback = cb;
+
+ return NO_ERROR;
+}
+
// client singleton for AudioPolicyService binder interface
// protected by gLockAPS
sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;
@@ -1333,6 +1344,32 @@ void AudioSystem::AudioPolicyServiceClient::onRecordingConfigurationUpdate(
}
}
+// ---------------------------------------------------------------------------
+
+status_t AudioSystem::listAudioSessions(audio_stream_type_t stream,
+ Vector< sp<AudioSessionInfo>> &sessions)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->listAudioSessions(stream, sessions);
+}
+
+void AudioSystem::AudioPolicyServiceClient::onOutputSessionEffectsUpdate(
+ sp<AudioSessionInfo>& info, bool added)
+{
+ ALOGV("AudioPolicyServiceClient::onOutputSessionEffectsUpdate(%d, %d, %d)",
+ info->mStream, info->mSessionId, added);
+ audio_session_callback cb = NULL;
+ {
+ Mutex::Autolock _l(AudioSystem::gLock);
+ cb = gAudioSessionCallback;
+ }
+
+ if (cb != NULL) {
+ cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, info, added);
+ }
+}
+
void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)
{
{
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index f071a020b1..ac1c71003e 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -78,7 +78,8 @@ enum {
SET_AUDIO_PORT_CALLBACK_ENABLED,
SET_MASTER_MONO,
GET_MASTER_MONO,
- GET_STREAM_VOLUME_DB
+ GET_STREAM_VOLUME_DB,
+ LIST_AUDIO_SESSIONS
};
#define MAX_ITEMS_PER_LIST 1024
@@ -842,6 +843,29 @@ public:
}
return reply.readFloat();
}
+
+ virtual status_t listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeInt32(streams);
+ status_t status = remote()->transact(LIST_AUDIO_SESSIONS, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+
+ status = reply.readInt32();
+ if (status == NO_ERROR) {
+ size_t size = (size_t)reply.readUint32();
+ for (size_t i = 0; i < size && reply.dataAvail() > 0; i++) {
+ sp<AudioSessionInfo> info = new AudioSessionInfo();
+ info->readFromParcel(reply);
+ sessions.push_back(info);
+ }
+ }
+ return status;
+ }
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1351,6 +1375,23 @@ status_t BnAudioPolicyService::onTransact(
return NO_ERROR;
} break;
+ case LIST_AUDIO_SESSIONS: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ audio_stream_type_t streams = (audio_stream_type_t)data.readInt32();
+
+ Vector< sp<AudioSessionInfo>> sessions;
+ status_t status = listAudioSessions(streams, sessions);
+
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeUint32(static_cast<uint32_t>(sessions.size()));
+ for (size_t i = 0; i < sessions.size(); i++) {
+ sessions[i]->writeToParcel(reply);
+ }
+ }
+ return NO_ERROR;
+ }
+
case ACQUIRE_SOUNDTRIGGER_SESSION: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>(
diff --git a/media/libaudioclient/IAudioPolicyServiceClient.cpp b/media/libaudioclient/IAudioPolicyServiceClient.cpp
index ad7f1dea55..2f7026f0a5 100644
--- a/media/libaudioclient/IAudioPolicyServiceClient.cpp
+++ b/media/libaudioclient/IAudioPolicyServiceClient.cpp
@@ -31,7 +31,8 @@ enum {
PORT_LIST_UPDATE = IBinder::FIRST_CALL_TRANSACTION,
PATCH_LIST_UPDATE,
MIX_STATE_UPDATE,
- RECORDING_CONFIGURATION_UPDATE
+ RECORDING_CONFIGURATION_UPDATE,
+ OUTPUT_SESSION_EFFECTS_UPDATE
};
// ----------------------------------------------------------------------
@@ -104,6 +105,19 @@ public:
data.writeInt32(patchHandle);
remote()->transact(RECORDING_CONFIGURATION_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
}
+
+ void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor());
+ data.writeInt32(info->mStream);
+ data.writeInt32(info->mSessionId);
+ data.writeInt32(info->mFlags);
+ data.writeInt32(info->mChannelMask);
+ data.writeInt32(info->mUid);
+ data.writeInt32(added ? 1 : 0);
+ remote()->transact(OUTPUT_SESSION_EFFECTS_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
+ }
};
IMPLEMENT_META_INTERFACE(AudioPolicyServiceClient, "android.media.IAudioPolicyServiceClient");
@@ -145,6 +159,20 @@ status_t BnAudioPolicyServiceClient::onTransact(
patchHandle);
return NO_ERROR;
} break;
+ case OUTPUT_SESSION_EFFECTS_UPDATE: {
+ CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
+ audio_stream_type_t stream = static_cast<audio_stream_type_t>(data.readInt32());
+ audio_session_t sessionId = static_cast<audio_session_t>(data.readInt32());
+ audio_output_flags_t flags = static_cast<audio_output_flags_t>(data.readInt32());
+ audio_channel_mask_t channelMask = static_cast<audio_channel_mask_t>(data.readInt32());
+ uid_t uid = static_cast<uid_t>(data.readInt32());
+ bool added = data.readInt32() > 0;
+
+ sp<AudioSessionInfo> info = new AudioSessionInfo(
+ sessionId, stream, flags, channelMask, uid);
+ onOutputSessionEffectsUpdate(info, added);
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 8da0069ccb..ba814a31d5 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -23,6 +23,7 @@
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/Vector.h>
+#include <media/AudioSession.h>
namespace android {
@@ -44,6 +45,7 @@ namespace android {
// AudioSystem's implementation of the AudioPolicyClient interface
// keep in sync with AudioSystem.java
#define DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE 0
+#define AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE 10
#define MIX_STATE_DISABLED (-1)
#define MIX_STATE_IDLE 0
diff --git a/media/libaudioclient/include/media/AudioSession.h b/media/libaudioclient/include/media/AudioSession.h
new file mode 100644
index 0000000000..2bae5212cf
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioSession.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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.
+ */
+
+#ifndef ANDROID_AUDIOSESSION_H
+#define ANDROID_AUDIOSESSION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <system/audio.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+// class to store streaminfo
+class AudioSessionInfo : public RefBase {
+public:
+ AudioSessionInfo(audio_session_t session, audio_stream_type_t stream, audio_output_flags_t flags,
+ audio_channel_mask_t channelMask, uid_t uid) :
+ mSessionId(session), mStream(stream), mFlags(flags), mChannelMask(channelMask),
+ mUid(uid), mRefCount(0) {}
+
+ AudioSessionInfo() : mSessionId((audio_session_t) 0), mStream(AUDIO_STREAM_DEFAULT), mFlags(AUDIO_OUTPUT_FLAG_NONE), mChannelMask(AUDIO_CHANNEL_NONE), mUid(0) {}
+
+ /*virtual*/ ~AudioSessionInfo() {}
+
+ audio_session_t mSessionId;
+ audio_stream_type_t mStream;
+ audio_output_flags_t mFlags;
+ audio_channel_mask_t mChannelMask;
+ uid_t mUid;
+
+ // AudioPolicyManager keeps mLock, no need for lock on reference count here
+ int mRefCount;
+
+ void readFromParcel(const Parcel &parcel) {
+ mSessionId = (audio_session_t) parcel.readInt32();
+ mStream = static_cast<audio_stream_type_t>(parcel.readInt32());
+ mFlags = static_cast<audio_output_flags_t>(parcel.readInt32());
+ mChannelMask = static_cast<audio_channel_mask_t>(parcel.readInt32());
+ mUid = static_cast<uid_t>(parcel.readInt32());
+ }
+
+ void writeToParcel(Parcel *parcel) const {
+ parcel->writeInt32(mSessionId);
+ parcel->writeInt32(mStream);
+ parcel->writeInt32(mFlags);
+ parcel->writeInt32(mChannelMask);
+ parcel->writeInt32(mUid);
+ }
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIOSESSION_H
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 5a81d835dc..feea961843 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -36,6 +36,8 @@ typedef void (*dynamic_policy_callback)(int event, String8 regId, int val);
typedef void (*record_config_callback)(int event, const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle);
+typedef void (*audio_session_callback)(int event,
+ sp<AudioSessionInfo>& session, bool added);
class IAudioFlinger;
class IAudioPolicyService;
@@ -100,6 +102,7 @@ public:
static void setErrorCallback(audio_error_callback cb);
static void setDynPolicyCallback(dynamic_policy_callback cb);
static void setRecordConfigCallback(record_config_callback);
+ static status_t setAudioSessionCallback(audio_session_callback cb);
// helper function to obtain AudioFlinger service handle
static const sp<IAudioFlinger> get_audio_flinger();
@@ -341,6 +344,9 @@ public:
static float getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device);
+ static status_t listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions);
+
// ----------------------------------------------------------------------------
class AudioPortCallback : public RefBase
@@ -444,6 +450,7 @@ private:
const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
+ virtual void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
private:
Mutex mLock;
@@ -464,6 +471,7 @@ private:
static audio_error_callback gAudioErrorCallback;
static dynamic_policy_callback gDynPolicyCallback;
static record_config_callback gRecordConfigCallback;
+ static audio_session_callback gAudioSessionCallback;
static size_t gInBuffSize;
// previous parameters for recording buffer size queries
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index eec3e881da..c01d7d042f 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -171,6 +171,9 @@ public:
virtual status_t getMasterMono(bool *mono) = 0;
virtual float getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device) = 0;
+
+ virtual status_t listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions) = 0;
};
diff --git a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
index e0d2495fad..fb7d7be2a0 100644
--- a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
+++ b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
@@ -21,6 +21,7 @@
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <system/audio.h>
+#include <media/AudioSession.h>
namespace android {
@@ -53,6 +54,8 @@ public:
const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle) = 0;
+ // Notifies when a default effect set is attached to a session/stream
+ virtual void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added) = 0;
};
diff --git a/media/libmedia/omx/1.0/WOmxNode.cpp b/media/libmedia/omx/1.0/WOmxNode.cpp
index 0b40e8d467..2cd8b760d1 100644
--- a/media/libmedia/omx/1.0/WOmxNode.cpp
+++ b/media/libmedia/omx/1.0/WOmxNode.cpp
@@ -151,7 +151,8 @@ status_t LWOmxNode::allocateSecureBuffer(
hidl_handle const& outNativeHandle) {
fnStatus = toStatusT(status);
*buffer = outBuffer;
- *native_handle = NativeHandle::create(
+ *native_handle = outNativeHandle.getNativeHandle() == nullptr ?
+ nullptr : NativeHandle::create(
native_handle_clone(outNativeHandle), true);
}));
return transStatus == NO_ERROR ? fnStatus : transStatus;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 89354d6d09..c58dcb9b08 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1566,7 +1566,7 @@ status_t StagefrightRecorder::setupCameraSource(
Size videoSize;
videoSize.width = mVideoWidth;
videoSize.height = mVideoHeight;
- if (mCaptureFpsEnable) {
+ if (mCaptureFpsEnable && mCaptureFps != mFrameRate) {
if (!(mCaptureFps > 0.)) {
ALOGE("Invalid mCaptureFps value: %lf", mCaptureFps);
return BAD_VALUE;
@@ -1706,6 +1706,7 @@ status_t StagefrightRecorder::setupVideoEncoder(
preferBFrames = false;
tsLayers = 2; // use at least two layers as resulting video will likely be sped up
} else if (mCaptureFps > maxPlaybackFps) { // slow-mo
+ format->setInt32("high-frame-rate", 1);
maxPlaybackFps = mCaptureFps; // assume video will be played back at full capture speed
preferBFrames = false;
}
@@ -1952,7 +1953,7 @@ status_t StagefrightRecorder::resume() {
mPauseStartTimeUs = bufferStartTimeUs;
}
// 30 ms buffer to avoid timestamp overlap
- mTotalPausedDurationUs += resumeStartTimeUs - mPauseStartTimeUs - 30000;
+ mTotalPausedDurationUs += (systemTime() / 1000) - mPauseStartTimeUs - 30000;
}
double timeOffset = -mTotalPausedDurationUs;
if (mCaptureFpsEnable) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index df360462d6..7e10631dc1 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2200,9 +2200,6 @@ void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) {
void NuPlayer::performReset() {
ALOGV("performReset");
- CHECK(mAudioDecoder == NULL);
- CHECK(mVideoDecoder == NULL);
-
cancelPollDuration();
++mScanSourcesGeneration;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index a2eb9a8c6b..def8ada3c3 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -7517,6 +7517,7 @@ status_t ACodec::setVendorParameters(const sp<AMessage> &params) {
// don't bother component if we don't have vendor extensions as they may not have implemented
// the android vendor extension support, which will lead to unnecessary OMX failure logs.
if (vendorKeys.empty()) {
+ mVendorExtensionsStatus = kExtensionsNone;
return OK;
}
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 6ed0d0eb43..399199e381 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -162,6 +162,10 @@ static int32_t getColorFormat(const char* colorFormat) {
return OMX_COLOR_FormatAndroidOpaque;
}
+ if (!strcmp(colorFormat, "YVU420SemiPlanar")) {
+ return OMX_QCOM_COLOR_FormatYVU420SemiPlanar;
+ }
+
ALOGE("Uknown color format (%s), please add it to "
"CameraSource::getColorFormat", colorFormat);
@@ -337,6 +341,12 @@ status_t CameraSource::isCameraColorFormatSupported(
return OK;
}
+static int32_t getHighSpeedFrameRate(const CameraParameters& params) {
+ const char* hsr = params.get("video-hsr");
+ int32_t rate = (hsr != NULL && strncmp(hsr, "off", 3)) ? strtol(hsr, NULL, 10) : 0;
+ return std::min(rate, 240);
+}
+
/*
* Configure the camera to use the requested video size
* (width and height) and/or frame rate. If both width and
@@ -384,11 +394,15 @@ status_t CameraSource::configureCamera(
}
if (frameRate != -1) {
- CHECK(frameRate > 0 && frameRate <= 120);
+ CHECK(frameRate > 0 && frameRate <= 240);
const char* supportedFrameRates =
params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES);
CHECK(supportedFrameRates != NULL);
ALOGV("Supported frame rates: %s", supportedFrameRates);
+ if (getHighSpeedFrameRate(*params)) {
+ ALOGI("Use default 30fps for HighSpeed %dfps", frameRate);
+ frameRate = 30;
+ }
char buf[4];
snprintf(buf, 4, "%d", frameRate);
if (strstr(supportedFrameRates, buf) == NULL) {
@@ -490,6 +504,8 @@ status_t CameraSource::checkFrameRate(
ALOGE("Failed to retrieve preview frame rate (%d)", frameRateActual);
return UNKNOWN_ERROR;
}
+ int32_t highSpeedRate = getHighSpeedFrameRate(params);
+ frameRateActual = highSpeedRate ? highSpeedRate : frameRateActual;
// Check the actual video frame rate against the target/requested
// video frame rate.
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 970526af66..492ecfe03e 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -281,7 +281,8 @@ bool CameraSourceTimeLapse::skipFrameAndModifyTimeStamp(int64_t *timestampUs) {
// The first 2 output frames from the encoder are: decoder specific info and
// the compressed video frame data for the first input video frame.
if (mNumFramesEncoded >= 1 && *timestampUs <
- (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs)) {
+ (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs) &&
+ (mTimeBetweenFrameCaptureUs > mTimeBetweenTimeLapseVideoFramesUs + 1)) {
// Skip all frames from last encoded frame until
// sufficient time (mTimeBetweenFrameCaptureUs) has passed.
// Tell the camera to release its recording frame and return.
@@ -296,6 +297,12 @@ bool CameraSourceTimeLapse::skipFrameAndModifyTimeStamp(int64_t *timestampUs) {
mLastTimeLapseFrameRealTimestampUs = *timestampUs;
*timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
+ // Update start-time once the captured-time reaches the expected start-time.
+ // Not doing so will result in CameraSource always dropping frames since
+ // updated-timestamp will never intersect start-timestamp
+ if ((mNumFramesReceived == 0 && mLastTimeLapseFrameRealTimestampUs >= mStartTimeUs)) {
+ mStartTimeUs = *timestampUs;
+ }
return false;
}
return false;
diff --git a/media/libstagefright/FLACExtractor.cpp b/media/libstagefright/FLACExtractor.cpp
index 1b88e5d25d..a96b3c3a19 100644
--- a/media/libstagefright/FLACExtractor.cpp
+++ b/media/libstagefright/FLACExtractor.cpp
@@ -585,6 +585,8 @@ status_t FLACParser::init()
case 48000:
case 88200:
case 96000:
+ case 176400:
+ case 192000:
break;
default:
ALOGE("unsupported sample rate %u", getSampleRate());
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 9c777b31c6..b710b81daa 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -317,8 +317,13 @@ static const char *FourCC2MIME(uint32_t fourcc) {
case FOURCC('h', 'e', 'v', '1'):
return MEDIA_MIMETYPE_VIDEO_HEVC;
default:
- CHECK(!"should not be here.");
- return NULL;
+ ALOGW("Unknown fourcc: %c%c%c%c",
+ (fourcc >> 24) & 0xff,
+ (fourcc >> 16) & 0xff,
+ (fourcc >> 8) & 0xff,
+ fourcc & 0xff
+ );
+ return "application/octet-stream";
}
}
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index d808e5bb46..7d52d41b19 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -748,8 +748,8 @@ status_t MediaCodecSource::feedEncoderInputBuffers() {
}
status_t MediaCodecSource::onStart(MetaData *params) {
- if (mStopping) {
- ALOGE("Failed to start while we're stopping");
+ if (mStopping || mOutput.lock()->mEncoderReachedEOS) {
+ ALOGE("Failed to start while we're stopping or encoder already stopped due to EOS error");
return INVALID_OPERATION;
}
int64_t startTimeUs;
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index 4ff2bfe189..9925dbf420 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -40,7 +40,8 @@ static bool FileHasAcceptableExtension(const char *extension) {
".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac",
".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota",
".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf",
- ".avi", ".mpeg", ".mpg", ".awb", ".mpga", ".mov"
+ ".avi", ".mpeg", ".mpg", ".awb", ".mpga", ".mov", ".opus",
+ ".m4v", ".oga"
};
static const size_t kNumValidExtensions =
sizeof(kValidExtensions) / sizeof(kValidExtensions[0]);
@@ -62,6 +63,11 @@ MediaScanResult StagefrightMediaScanner::processFile(
client.setLocale(locale());
client.beginFile();
MediaScanResult result = processFileInternal(path, mimeType, client);
+ ALOGV("result: %d", result);
+ if (mimeType == NULL && result != MEDIA_SCAN_RESULT_OK) {
+ ALOGW("media scan failed for %s", path);
+ client.setMimeType("application/octet-stream");
+ }
client.endFile();
return result;
}
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index ccce170913..e8c3dd38a7 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -494,13 +494,18 @@ static VideoFrame *extractVideoFrame(
ALOGV("Timed-out waiting for output.. retries left = %zu", retriesLeft);
err = OK;
} else if (err == OK) {
+ if (outputFormat == NULL) {
+ decoder->releaseOutputBuffer(index);
+ err = ERROR_MALFORMED;
+ break;
+ }
+
// If we're seeking with CLOSEST option and obtained a valid targetTimeUs
// from the extractor, decode to the specified frame. Otherwise we're done.
ALOGV("Received an output buffer, timeUs=%lld", (long long)timeUs);
sp<MediaCodecBuffer> videoFrameBuffer = outputBuffers.itemAt(index);
int32_t width, height;
- CHECK(outputFormat != NULL);
CHECK(outputFormat->findInt32("width", &width));
CHECK(outputFormat->findInt32("height", &height));
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index d14e86b1f2..c1ef653c15 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -389,7 +389,7 @@ void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
buffer_handle_t bufferHandle = getMediaBufferHandle(buffer);
for (size_t i = 0; i < mCurrentBuffers.size(); i++) {
- if (mCurrentBuffers[i]->handle == bufferHandle) {
+ if ((buffer_handle_t)mCurrentBuffers[i]->getNativeBuffer() == bufferHandle) {
mCurrentBuffers.removeAt(i);
foundBuffer = true;
break;
@@ -405,7 +405,7 @@ void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
continue;
}
- if (bufferHandle == mSlots[id].mGraphicBuffer->handle) {
+ if (bufferHandle == (buffer_handle_t)mSlots[id].mGraphicBuffer->getNativeBuffer()) {
ALOGV("Slot %d returned, matches handle = %p", id,
mSlots[id].mGraphicBuffer->handle);
diff --git a/media/libstagefright/SurfaceUtils.cpp b/media/libstagefright/SurfaceUtils.cpp
index b7c1598ecf..2dd6df8032 100644
--- a/media/libstagefright/SurfaceUtils.cpp
+++ b/media/libstagefright/SurfaceUtils.cpp
@@ -108,8 +108,9 @@ status_t setNativeWindowSizeFormatAndUsage(
}
}
- int finalUsage = usage | consumerUsage;
- ALOGV("gralloc usage: %#x(producer) + %#x(consumer) = %#x", usage, consumerUsage, finalUsage);
+ uint64_t finalUsage = (usage | consumerUsage) & 0xffffffffLL;
+ ALOGV("gralloc usage: %#x(producer) + %#x(consumer) = %#" PRIx64,
+ usage, consumerUsage, finalUsage);
err = native_window_set_usage(nativeWindow, finalUsage);
if (err != NO_ERROR) {
ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
@@ -123,7 +124,7 @@ status_t setNativeWindowSizeFormatAndUsage(
return err;
}
- ALOGD("set up nativeWindow %p for %dx%d, color %#x, rotation %d, usage %#x",
+ ALOGD("set up nativeWindow %p for %dx%d, color %#x, rotation %d, usage %#" PRIx64,
nativeWindow, width, height, format, rotation, finalUsage);
return NO_ERROR;
}
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 813a257e9f..cb3d1cb3f1 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -140,6 +140,7 @@ private:
enum Type {
AVC,
AAC,
+ HEVC,
OTHER
};
@@ -148,7 +149,7 @@ private:
Type mType;
bool mIsAudio;
BlockIterator mBlockIter;
- ssize_t mNALSizeLen; // for type AVC
+ ssize_t mNALSizeLen; // for type AVC or HEVC
List<MediaBuffer *> mPendingFrames;
@@ -244,6 +245,19 @@ MatroskaSource::MatroskaSource(
} else {
ALOGE("No mNALSizeLen");
}
+ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
+ mType = HEVC;
+
+ uint32_t dummy;
+ const uint8_t *hvcc;
+ size_t hvccSize;
+ if (meta->findData(kKeyHVCC, &dummy, (const void **)&hvcc, &hvccSize)
+ && hvccSize >= 22u) {
+ mNALSizeLen = 1 + (hvcc[14+7] & 3);
+ ALOGV("mNALSizeLen = %zu", mNALSizeLen);
+ } else {
+ ALOGE("No mNALSizeLen");
+ }
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
mType = AAC;
}
@@ -343,7 +357,15 @@ void BlockIterator::advance_l() {
res = mCluster->Parse(pos, len);
ALOGV("Parse (2) returned %ld", res);
- CHECK_GE(res, 0);
+
+ if (res < 0) {
+ // I/O error
+
+ ALOGE("Cluster::Parse returned result %ld", res);
+
+ mCluster = NULL;
+ break;
+ }
mBlockEntryIndex = 0;
continue;
@@ -692,7 +714,7 @@ status_t MatroskaSource::read(
MediaBuffer *frame = *mPendingFrames.begin();
mPendingFrames.erase(mPendingFrames.begin());
- if (mType != AVC || mNALSizeLen == 0) {
+ if ((mType != AVC && mType != HEVC) || mNALSizeLen == 0) {
if (targetSampleTimeUs >= 0ll) {
frame->meta_data()->setInt64(
kKeyTargetTime, targetSampleTimeUs);
@@ -1293,6 +1315,14 @@ void MatroskaExtractor::addTracks() {
if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize);
+ } else if (!strcmp("V_MPEGH/ISO/HEVC", codecID)) {
+ meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC);
+ if (codecPrivateSize > 0) {
+ meta->setData(kKeyHVCC, kTypeHVCC, codecPrivate, codecPrivateSize);
+ } else {
+ ALOGW("HEVC is detected, but does not have configuration.");
+ continue;
+ }
} else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) {
if (codecPrivateSize > 0) {
meta->setCString(
@@ -1398,6 +1428,8 @@ void MatroskaExtractor::addTracks() {
} else if (!strcmp("A_FLAC", codecID)) {
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC);
err = addFlacMetadata(meta, codecPrivate, codecPrivateSize);
+ } else if (!strcmp("A_AC3", codecID)) {
+ meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3);
} else {
ALOGW("%s is not supported.", codecID);
continue;
diff --git a/media/libstagefright/omx/1.0/WOmxNode.cpp b/media/libstagefright/omx/1.0/WOmxNode.cpp
index 9f822839a6..1dc7c7b6f0 100644
--- a/media/libstagefright/omx/1.0/WOmxNode.cpp
+++ b/media/libstagefright/omx/1.0/WOmxNode.cpp
@@ -154,7 +154,8 @@ status_t LWOmxNode::allocateSecureBuffer(
hidl_handle const& outNativeHandle) {
fnStatus = toStatusT(status);
*buffer = outBuffer;
- *native_handle = NativeHandle::create(
+ *native_handle = outNativeHandle.getNativeHandle() == nullptr ?
+ nullptr : NativeHandle::create(
native_handle_clone(outNativeHandle), true);
}));
return transStatus == NO_ERROR ? fnStatus : transStatus;
diff --git a/media/libstagefright/omx/Android.bp b/media/libstagefright/omx/Android.bp
index d4cdf693af..1a00fb9506 100644
--- a/media/libstagefright/omx/Android.bp
+++ b/media/libstagefright/omx/Android.bp
@@ -79,6 +79,17 @@ cc_library_shared {
"-Wno-documentation",
],
+ product_variables: {
+ lineage: {
+ needs_legacy_camera_hal1_dyn_native_handle: {
+ cppflags: ["-DNEEDS_LEGACY_CAMERA_HAL1_DYN_NATIVE_HANDLE"],
+ },
+ uses_qcom_bsp_legacy: {
+ cppflags: ["-DQCOM_BSP_LEGACY"],
+ },
+ },
+ },
+
sanitize: {
misc_undefined: [
"signed-integer-overflow",
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 1917d2add8..f74de85c2c 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -776,11 +776,13 @@ status_t GraphicBufferSource::submitBuffer_l(const VideoBuffer &item) {
return UNKNOWN_ERROR;
}
+#ifndef QCOM_BSP_LEGACY
if ((android_dataspace)item.mDataspace != mLastDataspace) {
onDataspaceChanged_l(
item.mDataspace,
(android_pixel_format)item.mBuffer->getGraphicBuffer()->format);
}
+#endif
std::shared_ptr<AcquiredBuffer> buffer = item.mBuffer;
// use a GraphicBuffer for now as OMXNodeInstance is using GraphicBuffers to hold references
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 0c2203ab79..04866d5baf 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -500,6 +500,9 @@ status_t OMXNodeInstance::freeNode() {
Mutex::Autolock _l(mLock);
+ if (mActiveBuffers.size() > 0) {
+ freeActiveBuffers();
+ }
status_t err = mOwner->freeNode(this);
mDispatcher.clear();
@@ -1078,6 +1081,9 @@ status_t OMXNodeInstance::useBuffer(
case OMXBuffer::kBufferTypeSharedMem: {
if (mPortMode[portIndex] != IOMX::kPortModePresetByteBuffer
+#ifdef NEEDS_LEGACY_CAMERA_HAL1_DYN_NATIVE_HANDLE
+ && mPortMode[portIndex] != IOMX::kPortModeDynamicNativeHandle
+#endif
&& mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer) {
break;
}
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index f7597db816..72fd887490 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -38,4 +38,15 @@ LOCAL_INIT_RC := mediaserver.rc
LOCAL_CFLAGS := -Werror -Wall
+ifeq ($(TARGET_HAS_LEGACY_CAMERA_HAL1),true)
+ LOCAL_CFLAGS += -DNO_CAMERA_SERVER
+
+ LOCAL_SHARED_LIBRARIES += \
+ libcameraservice \
+ libgui \
+ libhidltransport \
+ android.hardware.camera.common@1.0 \
+ android.hardware.camera.provider@2.4
+endif
+
include $(BUILD_EXECUTABLE)
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index ecddc48272..53b589350f 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -25,6 +25,10 @@
#include "RegisterExtensions.h"
// from LOCAL_C_INCLUDES
+#ifdef NO_CAMERA_SERVER
+#include "CameraService.h"
+#include <hidl/HidlTransportSupport.h>
+#endif
#include "IcuUtils.h"
#include "MediaPlayerService.h"
#include "ResourceManagerService.h"
@@ -35,12 +39,20 @@ int main(int argc __unused, char **argv __unused)
{
signal(SIGPIPE, SIG_IGN);
+#ifdef NO_CAMERA_SERVER
+ // Set 3 threads for HIDL calls
+ hardware::configureRpcThreadpool(3, /*willjoin*/ false);
+#endif
+
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
ALOGI("ServiceManager: %p", sm.get());
InitializeIcuOrDie();
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
+#ifdef NO_CAMERA_SERVER
+ CameraService::instantiate();
+#endif
registerExtensions();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index 8d894c17d1..9139925a8e 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -614,7 +614,7 @@ int MtpFfsHandle::start() {
int MtpFfsHandle::configure(bool usePtp) {
// Wait till previous server invocation has closed
- if (!mLock.try_lock_for(std::chrono::milliseconds(1000))) {
+ if (!mLock.try_lock_for(std::chrono::milliseconds(300))) {
LOG(ERROR) << "MtpServer was unable to get configure lock";
return -1;
}
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 2180462e87..89823c4ff8 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -132,7 +132,7 @@ int MtpServer::configure(bool usePtp) {
int ret = sHandle->configure(usePtp);
if (ret) ALOGE("Failed to configure MTP driver!");
- else android::base::SetProperty("sys.usb.ffs.mtp.ready", "1");
+ android::base::SetProperty("sys.usb.ffs.mtp.ready", "1");
return ret;
}
@@ -158,7 +158,7 @@ void MtpServer::removeStorage(MtpStorage* storage) {
MtpStorage* MtpServer::getStorage(MtpStorageID id) {
if (id == 0)
- return mStorages[0];
+ return mStorages.empty() ? nullptr : mStorages[0];
for (size_t i = 0; i < mStorages.size(); i++) {
MtpStorage* storage = mStorages[i];
if (storage->getStorageID() == id)
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index f313e901cd..35b83d3a7f 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -367,6 +367,13 @@ AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec *mData) {
}
EXPORT
+AMediaFormat* AMediaCodec_getBufferFormat(AMediaCodec *mData, size_t index) {
+ sp<AMessage> format;
+ mData->mCodec->getOutputFormat(index, &format);
+ return AMediaFormat_fromMsg(&format);
+}
+
+EXPORT
media_status_t AMediaCodec_releaseOutputBuffer(AMediaCodec *mData, size_t idx, bool render) {
if (render) {
return translate_error(mData->mCodec->renderOutputBufferAndRelease(idx));
diff --git a/media/ndk/include/media/NdkMediaCodec.h b/media/ndk/include/media/NdkMediaCodec.h
index 7e7e81ed0b..56f8b395e0 100644
--- a/media/ndk/include/media/NdkMediaCodec.h
+++ b/media/ndk/include/media/NdkMediaCodec.h
@@ -179,6 +179,12 @@ ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec*, AMediaCodecBufferInfo *inf
AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec*);
/**
+ * Get format of the buffer. The specified buffer index must have been previously obtained from
+ * dequeueOutputBuffer.
+ */
+AMediaFormat* AMediaCodec_getBufferFormat(AMediaCodec*, size_t index);
+
+/**
* If you are done with a buffer, use this call to return the buffer to
* the codec. If you previously specified a surface when configuring this
* video decoder you can optionally render the buffer.
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ff5f745f9b..e93605655e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1611,7 +1611,8 @@ sp<IAudioRecord> AudioFlinger::openRecord(
}
// check calling permissions
- if (!recordingAllowed(opPackageName, tid, clientUid)) {
+ if (!isTrustedCallingUid(callingUid) &&
+ !recordingAllowed(opPackageName, tid, callingUid)) {
ALOGE("openRecord() permission denied: recording not allowed");
lStatus = PERMISSION_DENIED;
goto Exit;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index bd5f146a82..7b8d4dcd04 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1590,6 +1590,10 @@ void AudioFlinger::EffectChain::clearInputBuffer()
return;
}
clearInputBuffer_l(thread);
+
+ for (size_t i = 0; i < mEffects.size(); i++) {
+ mEffects[i]->reset_l();
+ }
}
// Must be called with EffectChain::mLock locked
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 7b19f58b84..05916522e6 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -354,6 +354,8 @@ public:
const struct audio_config_base *clientConfig,
const struct audio_config_base *deviceConfig,
audio_patch_handle_t patchHandle) = 0;
+ virtual void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& streamInfo, bool added) = 0;
+
};
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 804f73ffd8..1fbf3e710e 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -78,6 +78,7 @@ public:
sp<AudioPort> mPort;
audio_devices_t mDevice; // current device this output is routed to
+ audio_io_handle_t mIoHandle; // output handle
uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output
nsecs_t mStopTime[AUDIO_STREAM_CNT];
float mCurVolume[AUDIO_STREAM_CNT]; // current stream volume in dB
@@ -123,7 +124,6 @@ public:
virtual void toAudioPort(struct audio_port *port) const;
const sp<IOProfile> mProfile; // I/O profile this output derives from
- audio_io_handle_t mIoHandle; // output handle
uint32_t mLatency; //
audio_output_flags_t mFlags; //
wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 3ac3cfff8f..59aceaf007 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -34,7 +34,7 @@ namespace android {
AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
AudioPolicyClientInterface *clientInterface)
- : mPort(port), mDevice(AUDIO_DEVICE_NONE),
+ : mPort(port), mDevice(AUDIO_DEVICE_NONE), mIoHandle(0),
mClientInterface(clientInterface), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0)
{
// clear usage count for all stream types
@@ -222,7 +222,7 @@ void AudioOutputDescriptor::log(const char* indent)
SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
AudioPolicyClientInterface *clientInterface)
: AudioOutputDescriptor(profile, clientInterface),
- mProfile(profile), mIoHandle(0), mLatency(0),
+ mProfile(profile), mLatency(0),
mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
mOutput1(0), mOutput2(0), mDirectOpenCount(0),
mDirectClientSession(AUDIO_SESSION_NONE), mGlobalRefCount(0)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index ed7a23b4d6..505c727684 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3557,7 +3557,7 @@ uint32_t AudioPolicyManager::nextAudioPortGeneration()
#ifdef USE_XML_AUDIO_POLICY_CONF
// Treblized audio policy xml config will be located in /odm/etc or /vendor/etc.
static const char *kConfigLocationList[] =
- {"/odm/etc", "/vendor/etc", "/system/etc"};
+ {"/odm/etc", "/vendor/etc/audio", "/vendor/etc", "/system/etc"};
static const int kConfigLocationListSize =
(sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index ea8d5c884a..8356b3f7cd 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -484,12 +484,12 @@ protected:
// if argument "device" is different from AUDIO_DEVICE_NONE, startSource() will force
// the re-evaluation of the output device.
- status_t startSource(const sp<AudioOutputDescriptor>& outputDesc,
+ virtual status_t startSource(const sp<AudioOutputDescriptor>& outputDesc,
audio_stream_type_t stream,
audio_devices_t device,
const char *address,
uint32_t *delayMs);
- status_t stopSource(const sp<AudioOutputDescriptor>& outputDesc,
+ virtual status_t stopSource(const sp<AudioOutputDescriptor>& outputDesc,
audio_stream_type_t stream,
bool forceDeviceUpdate);
@@ -594,7 +594,7 @@ protected:
// Audio Policy Engine Interface.
AudioPolicyManagerInterface *mEngine;
-private:
+protected:
// Add or remove AC3 DTS encodings based on user preferences.
void filterSurroundFormats(FormatVector *formatsPtr);
void filterSurroundChannelMasks(ChannelsVector *channelMasksPtr);
@@ -626,7 +626,7 @@ private:
SortedVector<audio_io_handle_t>& outputs /*out*/);
uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
// internal method to return the output handle for the given device and format
- audio_io_handle_t getOutputForDevice(
+ virtual audio_io_handle_t getOutputForDevice(
audio_devices_t device,
audio_session_t session,
audio_stream_type_t stream,
@@ -662,7 +662,7 @@ private:
sp<AudioPolicyMix> *policyMix = NULL);
// Called by setDeviceConnectionState().
- status_t setDeviceConnectionStateInt(audio_devices_t device,
+ virtual status_t setDeviceConnectionStateInt(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name);
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 31c9575fcd..becf50a4ea 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -228,6 +228,13 @@ void AudioPolicyService::AudioPolicyClient::onRecordingConfigurationUpdate(
clientConfig, deviceConfig, patchHandle);
}
+void AudioPolicyService::AudioPolicyClient::onOutputSessionEffectsUpdate(
+ sp<AudioSessionInfo>& info, bool added)
+{
+ mAudioPolicyService->onOutputSessionEffectsUpdate(info, added);
+}
+
+
audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId(audio_unique_id_use_t use)
{
return AudioSystem::newAudioUniqueId(use);
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 84b10731dc..50d4018b3d 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -30,6 +30,7 @@
#include <utils/SortedVector.h>
#include <cutils/config_utils.h>
#include <binder/IPCThreadState.h>
+#include "AudioPolicyService.h"
#include "AudioPolicyEffects.h"
#include "ServiceUtilities.h"
@@ -39,7 +40,8 @@ namespace android {
// AudioPolicyEffects Implementation
// ----------------------------------------------------------------------------
-AudioPolicyEffects::AudioPolicyEffects()
+AudioPolicyEffects::AudioPolicyEffects(AudioPolicyService *audioPolicyService) :
+ mAudioPolicyService(audioPolicyService)
{
status_t loadResult = loadAudioEffectXmlConfig();
if (loadResult < 0) {
@@ -235,6 +237,8 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
{
status_t status = NO_ERROR;
+ ALOGV("addOutputSessionEffects %d", audioSession);
+
Mutex::Autolock _l(mLock);
// create audio processors according to stream
// FIXME: should we have specific post processing settings for internal streams?
@@ -242,6 +246,22 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
if (stream >= AUDIO_STREAM_PUBLIC_CNT) {
stream = AUDIO_STREAM_MUSIC;
}
+
+ // send the streaminfo notification only once
+ ssize_t sidx = mOutputAudioSessionInfo.indexOfKey(audioSession);
+ if (sidx >= 0) {
+ // AudioSessionInfo is existing and we just need to increase ref count
+ sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(sidx);
+ info->mRefCount++;
+
+ if (info->mRefCount == 1) {
+ mAudioPolicyService->onOutputSessionEffectsUpdate(info, true);
+ }
+ ALOGV("addOutputSessionEffects(): session info %d refCount=%d", audioSession, info->mRefCount);
+ } else {
+ ALOGV("addOutputSessionEffects(): no output stream info found for stream");
+ }
+
ssize_t index = mOutputStreams.indexOfKey(stream);
if (index < 0) {
ALOGV("addOutputSessionEffects(): no output processing needed for this stream");
@@ -287,6 +307,86 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
return status;
}
+status_t AudioPolicyEffects::releaseOutputAudioSessionInfo(audio_io_handle_t /* output */,
+ audio_stream_type_t stream,
+ audio_session_t session)
+{
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock _l(mLock);
+
+ ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session);
+ if (idx >= 0) {
+ sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(idx);
+ if (info->mRefCount == 0) {
+ mOutputAudioSessionInfo.removeItemsAt(idx);
+ }
+ ALOGV("releaseOutputAudioSessionInfo() sessionId=%d refcount=%d",
+ session, info->mRefCount);
+ } else {
+ ALOGV("releaseOutputAudioSessionInfo() no session info found");
+ }
+ return NO_ERROR;
+}
+
+status_t AudioPolicyEffects::updateOutputAudioSessionInfo(audio_io_handle_t /* output */,
+ audio_stream_type_t stream,
+ audio_session_t session,
+ audio_output_flags_t flags,
+ const audio_config_t *config, uid_t uid)
+{
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock _l(mLock);
+
+ // TODO: Handle other stream types based on client registration
+ if (stream != AUDIO_STREAM_MUSIC) {
+ return NO_ERROR;
+ }
+
+ // update AudioSessionInfo. This is used in the stream open/close path
+ // to notify userspace applications about session creation and
+ // teardown, allowing the app to make decisions about effects for
+ // a particular stream. This is independent of the current
+ // output_session_processing feature which forcibly attaches a
+ // static list of effects to a stream.
+ ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session);
+ sp<AudioSessionInfo> info;
+ if (idx < 0) {
+ info = new AudioSessionInfo(session, stream, flags, config->channel_mask, uid);
+ mOutputAudioSessionInfo.add(session, info);
+ } else {
+ // the streaminfo may actually change
+ info = mOutputAudioSessionInfo.valueAt(idx);
+ info->mFlags = flags;
+ info->mChannelMask = config->channel_mask;
+ }
+
+ ALOGV("updateOutputAudioSessionInfo() sessionId=%d, flags=0x%x, channel_mask=0x%x uid=%d refCount=%d",
+ info->mSessionId, info->mFlags, info->mChannelMask, info->mUid, info->mRefCount);
+
+ return NO_ERROR;
+}
+
+status_t AudioPolicyEffects::listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions)
+{
+ ALOGV("listAudioSessions() streams %d", streams);
+
+ for (unsigned int i = 0; i < mOutputAudioSessionInfo.size(); i++) {
+ sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(i);
+ if (streams == -1 || info->mStream == streams) {
+ sessions.push_back(info);
+ }
+ }
+
+ return NO_ERROR;
+}
+
status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t audioSession)
@@ -296,7 +396,19 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu
(void) stream; // argument not used for now
Mutex::Autolock _l(mLock);
- ssize_t index = mOutputSessions.indexOfKey(audioSession);
+ ssize_t index = mOutputAudioSessionInfo.indexOfKey(audioSession);
+ if (index >= 0) {
+ sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(index);
+ info->mRefCount--;
+ if (info->mRefCount == 0) {
+ mAudioPolicyService->onOutputSessionEffectsUpdate(info, false);
+ }
+ ALOGV("releaseOutputSessionEffects(): session=%d refCount=%d", info->mSessionId, info->mRefCount);
+ } else {
+ ALOGV("releaseOutputSessionEffects: no stream info was attached to this stream");
+ }
+
+ index = mOutputSessions.indexOfKey(audioSession);
if (index < 0) {
ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream");
return NO_ERROR;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 59d5d14559..04d1923218 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -28,6 +28,8 @@
namespace android {
+class AudioPolicyService;
+
// ----------------------------------------------------------------------------
// AudioPolicyEffects class
@@ -41,7 +43,7 @@ public:
// The constructor will parse audio_effects.conf
// First it will look whether vendor specific file exists,
// otherwise it will parse the system default file.
- AudioPolicyEffects();
+ AudioPolicyEffects(AudioPolicyService *audioPolicyService);
virtual ~AudioPolicyEffects();
// NOTE: methods on AudioPolicyEffects should never be called with the AudioPolicyService
@@ -82,6 +84,19 @@ public:
audio_stream_type_t stream,
audio_session_t audioSession);
+ status_t updateOutputAudioSessionInfo(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t audioSession,
+ audio_output_flags_t flags,
+ const audio_config_t *config, uid_t uid);
+
+ status_t releaseOutputAudioSessionInfo(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t audioSession);
+
+ status_t listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions);
+
private:
// class to store the description of an effects and its parameters
@@ -190,6 +205,10 @@ private:
KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams;
// Automatic output effects are unique for audiosession ID
KeyedVector< audio_session_t, EffectVector* > mOutputSessions;
+ // Stream info for session events
+ KeyedVector< audio_session_t, sp<AudioSessionInfo> > mOutputAudioSessionInfo;
+
+ AudioPolicyService *mAudioPolicyService;
};
}; // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index b7bce55c4c..56367cd525 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -173,18 +173,30 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
- ALOGV("getOutput()");
- Mutex::Autolock _l(mLock);
+ ALOGV("getOutputForAttr()");
+ status_t status = NO_ERROR;
+ sp<AudioPolicyEffects> audioPolicyEffects;
+ {
+ Mutex::Autolock _l(mLock);
- const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- if (!isTrustedCallingUid(callingUid) || uid == (uid_t)-1) {
- ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
- "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
- uid = callingUid;
+ const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ if (!isTrustedCallingUid(callingUid) || uid == (uid_t)-1) {
+ ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
+ "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
+ uid = callingUid;
+ }
+ status = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid,
+ config, flags, selectedDeviceId, portId);
+
+ audioPolicyEffects = mAudioPolicyEffects;
}
- return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid,
- config,
- flags, selectedDeviceId, portId);
+
+ if (status == NO_ERROR && audioPolicyEffects != 0) {
+ audioPolicyEffects->updateOutputAudioSessionInfo(*output,
+ *stream, session, flags, config, uid);
+ }
+
+ return status;
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
@@ -266,8 +278,16 @@ void AudioPolicyService::doReleaseOutput(audio_io_handle_t output,
audio_session_t session)
{
ALOGV("doReleaseOutput from tid %d", gettid());
- Mutex::Autolock _l(mLock);
- mAudioPolicyManager->releaseOutput(output, stream, session);
+ sp<AudioPolicyEffects>audioPolicyEffects;
+ {
+ Mutex::Autolock _l(mLock);
+ audioPolicyEffects = mAudioPolicyEffects;
+ mAudioPolicyManager->releaseOutput(output, stream, session);
+ }
+ if (audioPolicyEffects != 0) {
+ audioPolicyEffects->releaseOutputAudioSessionInfo(output,
+ stream, session);
+ }
}
status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
@@ -331,7 +351,7 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
// FIXME: use the same permission as for remote submix for now.
case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
- if (!captureAudioOutputAllowed(pid, uid)) {
+ if (!isTrustedCallingUid(callingUid) && !captureAudioOutputAllowed(pid, uid)) {
ALOGE("getInputForAttr() permission denied: capture not allowed");
status = PERMISSION_DENIED;
}
@@ -772,7 +792,6 @@ status_t AudioPolicyService::getMasterMono(bool *mono)
return mAudioPolicyManager->getMasterMono(mono);
}
-
float AudioPolicyService::getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device)
{
@@ -783,5 +802,24 @@ float AudioPolicyService::getStreamVolumeDB(
return mAudioPolicyManager->getStreamVolumeDB(stream, index, device);
}
+status_t AudioPolicyService::listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions)
+{
+ sp<AudioPolicyEffects> audioPolicyEffects;
+ {
+ Mutex::Autolock _l(mLock);
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ audioPolicyEffects = mAudioPolicyEffects;
+ }
+
+ if (audioPolicyEffects != 0) {
+ return audioPolicyEffects->listAudioSessions(streams, sessions);
+ }
+
+ // no errors here if effects are not available
+ return NO_ERROR;
+}
}; // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index b417631085..b421f6d2ad 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -74,7 +74,7 @@ void AudioPolicyService::onFirstRef()
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
}
// load audio processing modules
- sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
+ sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects(this);
{
Mutex::Autolock _l(mLock);
mAudioPolicyEffects = audioPolicyEffects;
@@ -223,6 +223,21 @@ status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_co
return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
}
+void AudioPolicyService::onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
+{
+ ALOGV("AudioPolicyService::onOutputSessionEffectsUpdate(%d, %d, %d)",
+ info->mStream, info->mSessionId, added);
+ mOutputCommandThread->effectSessionUpdateCommand(info, added);
+}
+
+void AudioPolicyService::doOnOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
+{
+ Mutex::Autolock _l(mNotificationClientsLock);
+ for (size_t i = 0; i < mNotificationClients.size(); i++) {
+ mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(info, added);
+ }
+}
+
AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
const sp<IAudioPolicyServiceClient>& client,
uid_t uid)
@@ -258,6 +273,14 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
}
}
+void AudioPolicyService::NotificationClient::onOutputSessionEffectsUpdate(
+ sp<AudioSessionInfo>& info, bool added)
+{
+ if (mAudioPolicyServiceClient != 0) {
+ mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(info, added);
+ }
+}
+
void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
const String8& regId, int32_t state)
{
@@ -549,6 +572,21 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
data->mPatchHandle);
mLock.lock();
} break;
+ case EFFECT_SESSION_UPDATE: {
+ EffectSessionUpdateData *data =
+ (EffectSessionUpdateData *)command->mParam.get();
+ ALOGV("AudioCommandThread() processing effect session update %d %d %d",
+ data->mAudioSessionInfo->mStream, data->mAudioSessionInfo->mSessionId,
+ data->mAdded);
+ svc = mService.promote();
+ if (svc == 0) {
+ break;
+ }
+ mLock.unlock();
+ svc->doOnOutputSessionEffectsUpdate(data->mAudioSessionInfo, data->mAdded);
+ mLock.lock();
+ } break;
+
default:
ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
}
@@ -828,6 +866,20 @@ void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand
sendCommand(command);
}
+void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand(
+ sp<AudioSessionInfo>& streamInfo, bool added)
+{
+ sp<AudioCommand> command = new AudioCommand();
+ command->mCommand = EFFECT_SESSION_UPDATE;
+ EffectSessionUpdateData *data = new EffectSessionUpdateData();
+ data->mAudioSessionInfo = streamInfo;
+ data->mAdded = added;
+ command->mParam = data;
+ ALOGV("AudioCommandThread() sending effect session update (id=%d) for stream %d (added=%d)",
+ streamInfo->mStream, streamInfo->mSessionId, added);
+ sendCommand(command);
+}
+
status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
{
{
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 38d4b179fa..0525ba13fe 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -205,6 +205,9 @@ public:
virtual float getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device);
+ virtual status_t listAudioSessions(audio_stream_type_t stream,
+ Vector< sp<AudioSessionInfo>>& sessions);
+
status_t doStopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
@@ -235,6 +238,9 @@ public:
const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
+ void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
+ void doOnOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
+
private:
AudioPolicyService() ANDROID_API;
virtual ~AudioPolicyService();
@@ -266,7 +272,8 @@ private:
UPDATE_AUDIOPATCH_LIST,
SET_AUDIOPORT_CONFIG,
DYN_POLICY_MIX_STATE_UPDATE,
- RECORDING_CONFIGURATION_UPDATE
+ RECORDING_CONFIGURATION_UPDATE,
+ EFFECT_SESSION_UPDATE,
};
AudioCommandThread (String8 name, const wp<AudioPolicyService>& service);
@@ -312,6 +319,7 @@ private:
const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle);
void insertCommand_l(AudioCommand *command, int delayMs = 0);
+ void effectSessionUpdateCommand(sp<AudioSessionInfo>& info, bool added);
private:
class AudioCommandData;
@@ -410,6 +418,12 @@ private:
audio_patch_handle_t mPatchHandle;
};
+ class EffectSessionUpdateData : public AudioCommandData {
+ public:
+ sp<AudioSessionInfo> mAudioSessionInfo;
+ bool mAdded;
+ };
+
Mutex mLock;
Condition mWaitWorkCV;
Vector < sp<AudioCommand> > mAudioCommands; // list of pending commands
@@ -523,6 +537,9 @@ private:
virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
+ virtual void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added);
+
+
private:
AudioPolicyService *mAudioPolicyService;
};
@@ -544,7 +561,8 @@ private:
const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle);
void setAudioPortCallbacksEnabled(bool enabled);
-
+ void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info,
+ bool added);
// IBinder::DeathRecipient
virtual void binderDied(const wp<IBinder>& who);
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 7ec3ccbb51..762959430e 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -80,6 +80,12 @@ LOCAL_SHARED_LIBRARIES:= \
android.hardware.camera.device@3.2 \
android.hardware.camera.device@3.3
+ifeq ($(TARGET_USES_QTI_CAMERA_DEVICE), true)
+LOCAL_CFLAGS += -DQTI_CAMERA_DEVICE
+LOCAL_SHARED_LIBRARIES += \
+ vendor.qti.hardware.camera.device@1.0
+endif
+
LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder libcamera_client libfmq
LOCAL_C_INCLUDES += \
@@ -94,6 +100,10 @@ LOCAL_CFLAGS += -Wall -Wextra -Werror
# Workaround for invalid unused-lambda-capture warning http://b/38349491
LOCAL_CLANG_CFLAGS += -Wno-error=unused-lambda-capture
+ifeq ($(TARGET_HAS_LEGACY_CAMERA_HAL1),true)
+ LOCAL_CFLAGS += -DNO_CAMERA_SERVER
+endif
+
LOCAL_MODULE:= libcameraservice
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 20bd5e4479..3755d55cdb 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -744,7 +744,11 @@ int32_t CameraService::mapToInterface(StatusInternal status) {
Status CameraService::initializeShimMetadata(int cameraId) {
int uid = getCallingUid();
+#ifdef NO_CAMERA_SERVER
+ String16 internalPackageName("media");
+#else
String16 internalPackageName("cameraserver");
+#endif
String8 id = String8::format("%d", cameraId);
Status ret = Status::ok();
sp<Client> tmp = nullptr;
@@ -825,7 +829,9 @@ Status CameraService::getLegacyParametersLazy(int cameraId,
static bool isTrustedCallingUid(uid_t uid) {
switch (uid) {
case AID_MEDIA: // mediaserver
+#ifndef NO_CAMERA_SERVER
case AID_CAMERASERVER: // cameraserver
+#endif
case AID_RADIO: // telephony
return true;
default:
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 2cf648f111..585d2ebd5f 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -859,6 +859,12 @@ status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
outputStreams.push(getPreviewStreamId());
+ if (params.isDeviceZslSupported) {
+ // If device ZSL is supported, resume preview buffers that may be paused
+ // during last takePicture().
+ mDevice->dropStreamBuffers(false, getPreviewStreamId());
+ }
+
if (!params.recordingHint) {
if (!restart) {
res = mStreamingProcessor->updatePreviewRequest(params);
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index a407d0bb59..48757acdfc 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -59,6 +59,9 @@ CameraClient::CameraClient(const sp<CameraService>& cameraService,
mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
mLegacyMode = legacyMode;
mPlayShutterSound = true;
+
+ mLongshotEnabled = false;
+ mBurstCnt = 0;
LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
}
@@ -365,12 +368,14 @@ status_t CameraClient::setPreviewCallbackTarget(
// start preview mode
status_t CameraClient::startPreview() {
+ Mutex::Autolock lock(mLock);
LOG1("startPreview (pid %d)", getCallingPid());
return startCameraMode(CAMERA_PREVIEW_MODE);
}
// start recording mode
status_t CameraClient::startRecording() {
+ Mutex::Autolock lock(mLock);
LOG1("startRecording (pid %d)", getCallingPid());
return startCameraMode(CAMERA_RECORDING_MODE);
}
@@ -378,7 +383,6 @@ status_t CameraClient::startRecording() {
// start preview or recording
status_t CameraClient::startCameraMode(camera_mode mode) {
LOG1("startCameraMode(%d)", mode);
- Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
@@ -659,6 +663,10 @@ status_t CameraClient::takePicture(int msgType) {
CAMERA_MSG_COMPRESSED_IMAGE);
enableMsgType(picMsgType);
+ mBurstCnt = mHardware->getParameters().getInt("num-snaps-per-shutter");
+ if(mBurstCnt <= 0)
+ mBurstCnt = 1;
+ LOG1("mBurstCnt = %d", mBurstCnt);
return mHardware->takePicture();
}
@@ -760,6 +768,20 @@ status_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
} else if (cmd == CAMERA_CMD_PING) {
// If mHardware is 0, checkPidAndHardware will return error.
return OK;
+ } else if (cmd == CAMERA_CMD_HISTOGRAM_ON) {
+ enableMsgType(CAMERA_MSG_STATS_DATA);
+ } else if (cmd == CAMERA_CMD_HISTOGRAM_OFF) {
+ disableMsgType(CAMERA_MSG_STATS_DATA);
+ } else if (cmd == CAMERA_CMD_METADATA_ON) {
+ enableMsgType(CAMERA_MSG_META_DATA);
+ } else if (cmd == CAMERA_CMD_METADATA_OFF) {
+ disableMsgType(CAMERA_MSG_META_DATA);
+ } else if ( cmd == CAMERA_CMD_LONGSHOT_ON ) {
+ mLongshotEnabled = true;
+ } else if ( cmd == CAMERA_CMD_LONGSHOT_OFF ) {
+ mLongshotEnabled = false;
+ disableMsgType(CAMERA_MSG_SHUTTER);
+ disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
}
return mHardware->sendCommand(cmd, arg1, arg2);
@@ -955,7 +977,9 @@ void CameraClient::handleShutter(void) {
c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
}
- disableMsgType(CAMERA_MSG_SHUTTER);
+ if ( !mLongshotEnabled ) {
+ disableMsgType(CAMERA_MSG_SHUTTER);
+ }
// Shutters only happen in response to takePicture, so mark device as
// idle now, until preview is restarted
@@ -1040,7 +1064,13 @@ void CameraClient::handleRawPicture(const sp<IMemory>& mem) {
// picture callback - compressed picture ready
void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
- disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
+ if (mBurstCnt)
+ mBurstCnt--;
+
+ if (!mBurstCnt && !mLongshotEnabled) {
+ LOG1("handleCompressedPicture mBurstCnt = %d", mBurstCnt);
+ disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
+ }
sp<hardware::ICameraClient> c = mRemoteCallback;
mLock.unlock();
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index 7f93fef93c..a0d9d0add4 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -178,6 +178,9 @@ private:
// This function keeps trying to grab mLock, or give up if the message
// is found to be disabled. It returns true if mLock is grabbed.
bool lockIfMessageWanted(int32_t msgType);
+
+ bool mLongshotEnabled;
+ int mBurstCnt;
};
}
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index b65f1c76ca..1ee216fd9a 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -553,6 +553,12 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
return DONE;
}
+ if (l.mParameters.isDeviceZslSupported) {
+ // If device ZSL is supported, drop all pending preview buffers to reduce the chance of
+ // rendering preview frames newer than the still frame.
+ client->getCameraDevice()->dropStreamBuffers(true, client->getPreviewStreamId());
+ }
+
/**
* Clear the streaming request for still-capture pictures
* (as opposed to i.e. video snapshots)
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 3919bfa7c8..a90050e1bf 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -349,6 +349,11 @@ class CameraDeviceBase : public virtual RefBase {
virtual status_t setConsumerSurfaces(int streamId,
const std::vector<sp<Surface>>& consumers) = 0;
+ /**
+ * Drop buffers for stream of streamId if dropping is true. If dropping is false, do not
+ * drop buffers for stream of streamId.
+ */
+ virtual status_t dropStreamBuffers(bool /*dropping*/, int /*streamId*/) = 0;
};
}; // namespace android
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
index 522d521b5b..498485430e 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
@@ -136,6 +136,27 @@ hardware::Return<void> CameraHardwareInterface::dataCallback(
return hardware::Void();
}
+#ifdef QTI_CAMERA_DEVICE
+hardware::Return<void> CameraHardwareInterface::QDataCallback(
+ DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
+ const vendor::qti::hardware::camera::device::V1_0::QCameraFrameMetadata& metadata) {
+ camera_memory_t* mem = nullptr;
+ {
+ std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
+ if (mHidlMemPoolMap.count(data) == 0) {
+ ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+ return hardware::Void();
+ }
+ mem = mHidlMemPoolMap.at(data);
+ }
+ camera_frame_metadata_t md;
+ md.number_of_faces = metadata.faces.size();
+ md.faces = (camera_face_t*) metadata.faces.data();
+ sDataCb((int32_t) msgType, mem, bufferIndex, &md, this);
+ return hardware::Void();
+}
+#endif
+
hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
DataCallbackMsg msgType, uint32_t data,
uint32_t bufferIndex, int64_t timestamp) {
@@ -579,12 +600,16 @@ void CameraHardwareInterface::releaseRecordingFrame(const sp<IMemory>& mem)
if (CC_LIKELY(mHidlDevice != nullptr)) {
if (size == sizeof(VideoNativeHandleMetadata)) {
VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
- // Caching the handle here because md->pHandle will be subject to HAL's edit
- native_handle_t* nh = md->pHandle;
- hidl_handle frame = nh;
- mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
- native_handle_close(nh);
- native_handle_delete(nh);
+ if (md->eType == kMetadataBufferTypeNativeHandleSource) {
+ // Caching the handle here because md->pHandle will be subject to HAL's edit
+ native_handle_t* nh = md->pHandle;
+ hidl_handle frame = nh;
+ mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
+ native_handle_close(nh);
+ native_handle_delete(nh);
+ } else {
+ mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
+ }
} else {
mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
}
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index e519b04cdd..4a20b6a597 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -29,6 +29,9 @@
#include <hardware/camera.h>
#include <common/CameraProviderManager.h>
+#ifdef QTI_CAMERA_DEVICE
+#include <vendor/qti/hardware/camera/device/1.0/IQCameraDeviceCallback.h>
+#endif
namespace android {
@@ -85,7 +88,11 @@ typedef void (*data_callback_timestamp_batch)(
class CameraHardwareInterface :
public virtual RefBase,
+#ifdef QTI_CAMERA_DEVICE
+ public virtual vendor::qti::hardware::camera::device::V1_0::IQCameraDeviceCallback,
+#else
public virtual hardware::camera::device::V1_0::ICameraDeviceCallback,
+#endif
public virtual hardware::camera::device::V1_0::ICameraDevicePreviewCallback {
public:
@@ -395,6 +402,12 @@ private:
hardware::camera::device::V1_0::DataCallbackMsg msgType,
const hardware::hidl_vec<
hardware::camera::device::V1_0::HandleTimestampMessage>&) override;
+#ifdef QTI_CAMERA_DEVICE
+ hardware::Return<void> QDataCallback(
+ hardware::camera::device::V1_0::DataCallbackMsg msgType,
+ uint32_t data, uint32_t bufferIndex,
+ const vendor::qti::hardware::camera::device::V1_0::QCameraFrameMetadata& metadata) override;
+#endif
/**
* Implementation of android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index ced1d3af42..a980cde235 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1977,6 +1977,20 @@ status_t Camera3Device::setConsumerSurfaces(int streamId,
return OK;
}
+status_t Camera3Device::dropStreamBuffers(bool dropping, int streamId) {
+ Mutex::Autolock il(mInterfaceLock);
+ Mutex::Autolock l(mLock);
+
+ int idx = mOutputStreams.indexOfKey(streamId);
+ if (idx == NAME_NOT_FOUND) {
+ ALOGE("%s: Stream %d is not found.", __FUNCTION__, streamId);
+ return BAD_VALUE;
+ }
+
+ sp<Camera3OutputStreamInterface> stream = mOutputStreams.editValueAt(idx);
+ return stream->dropBuffers(dropping);
+}
+
/**
* Camera3Device private methods
*/
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index fbbbd08ce9..081af1978b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -178,6 +178,12 @@ class Camera3Device :
*/
status_t setConsumerSurfaces(int streamId, const std::vector<sp<Surface>>& consumers) override;
+ /**
+ * Drop buffers for stream of streamId if dropping is true. If dropping is false, do not
+ * drop buffers for stream of streamId.
+ */
+ status_t dropStreamBuffers(bool dropping, int streamId) override;
+
private:
// internal typedefs
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
index 6e2978f164..84fb8909d8 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
@@ -108,6 +108,10 @@ bool Camera3DummyStream::isConsumerConfigurationDeferred(size_t /*surface_id*/)
return false;
}
+status_t Camera3DummyStream::dropBuffers(bool /*dropping*/) {
+ return OK;
+}
+
status_t Camera3DummyStream::setConsumers(const std::vector<sp<Surface>>& /*consumers*/) {
ALOGE("%s: Stream %d: Dummy stream doesn't support set consumer surface!",
__FUNCTION__, mId);
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.h b/services/camera/libcameraservice/device3/Camera3DummyStream.h
index 492fb49eb1..9710765c2a 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.h
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.h
@@ -57,6 +57,12 @@ class Camera3DummyStream :
virtual status_t detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd);
/**
+ * Drop buffers for stream of streamId if dropping is true. If dropping is false, do not
+ * drop buffers for stream of streamId.
+ */
+ virtual status_t dropBuffers(bool /*dropping*/) override;
+
+ /**
* Return if this output stream is for video encoding.
*/
bool isVideoStream() const;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index dcaefe374e..8460c34d00 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -44,6 +44,7 @@ Camera3OutputStream::Camera3OutputStream(int id,
mUseBufferManager(false),
mTimestampOffset(timestampOffset),
mConsumerUsage(0),
+ mDropBuffers(false),
mDequeueBufferLatency(kDequeueLatencyBinSize) {
if (mConsumer == NULL) {
@@ -70,6 +71,7 @@ Camera3OutputStream::Camera3OutputStream(int id,
mUseBufferManager(false),
mTimestampOffset(timestampOffset),
mConsumerUsage(0),
+ mDropBuffers(false),
mDequeueBufferLatency(kDequeueLatencyBinSize) {
if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
@@ -100,6 +102,7 @@ Camera3OutputStream::Camera3OutputStream(int id,
mUseBufferManager(false),
mTimestampOffset(timestampOffset),
mConsumerUsage(consumerUsage),
+ mDropBuffers(false),
mDequeueBufferLatency(kDequeueLatencyBinSize) {
// Deferred consumer only support preview surface format now.
if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
@@ -139,6 +142,7 @@ Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type,
mUseBufferManager(false),
mTimestampOffset(timestampOffset),
mConsumerUsage(consumerUsage),
+ mDropBuffers(false),
mDequeueBufferLatency(kDequeueLatencyBinSize) {
if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
@@ -227,9 +231,14 @@ status_t Camera3OutputStream::returnBufferCheckedLocked(
/**
* Return buffer back to ANativeWindow
*/
- if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
+ if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR || mDropBuffers) {
// Cancel buffer
- ALOGW("A frame is dropped for stream %d", mId);
+ if (mDropBuffers) {
+ ALOGV("%s: Dropping a frame for stream %d.", __FUNCTION__, mId);
+ } else {
+ ALOGW("%s: A frame is dropped for stream %d due to buffer error.", __FUNCTION__, mId);
+ }
+
res = currentConsumer->cancelBuffer(currentConsumer.get(),
anwBuffer,
anwReleaseFence);
@@ -777,6 +786,12 @@ status_t Camera3OutputStream::detachBufferLocked(sp<GraphicBuffer>* buffer, int*
return res;
}
+status_t Camera3OutputStream::dropBuffers(bool dropping) {
+ Mutex::Autolock l(mLock);
+ mDropBuffers = dropping;
+ return OK;
+}
+
status_t Camera3OutputStream::notifyBufferReleased(ANativeWindowBuffer* /*anwBuffer*/) {
return OK;
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 7023d5d623..4865be7d31 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -166,6 +166,11 @@ class Camera3OutputStream :
virtual status_t notifyBufferReleased(ANativeWindowBuffer *anwBuffer);
/**
+ * Drop buffers if dropping is true. If dropping is false, do not drop buffers.
+ */
+ virtual status_t dropBuffers(bool dropping) override;
+
+ /**
* Set the graphic buffer manager to get/return the stream buffers.
*
* It is only legal to call this method when stream is in STATE_CONSTRUCTED state.
@@ -247,6 +252,9 @@ class Camera3OutputStream :
*/
uint64_t mConsumerUsage;
+ // Whether to drop valid buffers.
+ bool mDropBuffers;
+
/**
* Internal Camera3Stream interface
*/
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index 8107dd02b0..1719d74a1c 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -59,6 +59,11 @@ class Camera3OutputStreamInterface : public virtual Camera3StreamInterface {
*
*/
virtual status_t detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd) = 0;
+
+ /**
+ * Drop buffers if dropping is true. If dropping is false, do not drop buffers.
+ */
+ virtual status_t dropBuffers(bool /*dropping*/) = 0;
};
} // namespace camera3
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 22519a32fd..f2caaa65f5 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -256,6 +256,37 @@ void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognitio
if (module == NULL) {
return;
}
+ struct sound_trigger_phrase_recognition_event newEvent;
+ if (event-> type == SOUND_MODEL_TYPE_KEYPHRASE && event->data_size != 0
+ && event->data_offset != sizeof(struct sound_trigger_phrase_recognition_event)) {
+ // set some defaults for the phrase if the recognition event won't be parsed properly
+ // TODO: read defaults from the config
+
+ memset(&newEvent, 0, sizeof(struct sound_trigger_phrase_recognition_event));
+
+ sp<Model> model = module->getModel(event->model);
+
+ newEvent.num_phrases = 1;
+ newEvent.phrase_extras[0].id = 100;
+ newEvent.phrase_extras[0].recognition_modes = RECOGNITION_MODE_VOICE_TRIGGER;
+ newEvent.phrase_extras[0].confidence_level = 100;
+ newEvent.phrase_extras[0].num_levels = 1;
+ newEvent.phrase_extras[0].levels[0].level = 100;
+ newEvent.phrase_extras[0].levels[0].user_id = 100;
+ newEvent.common.status = event->status;
+ newEvent.common.type = event->type;
+ newEvent.common.model = event->model;
+ newEvent.common.capture_available = event->capture_available;
+ newEvent.common.capture_session = event->capture_session;
+ newEvent.common.capture_delay_ms = event->capture_delay_ms;
+ newEvent.common.capture_preamble_ms = event->capture_preamble_ms;
+ newEvent.common.trigger_in_data = event->trigger_in_data;
+ newEvent.common.audio_config = event->audio_config;
+ newEvent.common.data_size = event->data_size;
+ newEvent.common.data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
+
+ event = &newEvent.common;
+ }
sp<IMemory> eventMemory = prepareRecognitionEvent_l(event);
if (eventMemory == 0) {
return;