Merge "aaudio: show format as text"
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index 0982bba..a16e747 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -85,6 +85,10 @@
return mStreamUseCase;
}
+int OutputConfiguration::getTimestampBase() const {
+ return mTimestampBase;
+}
+
OutputConfiguration::OutputConfiguration() :
mRotation(INVALID_ROTATION),
mSurfaceSetID(INVALID_SET_ID),
@@ -95,7 +99,8 @@
mIsShared(false),
mIsMultiResolution(false),
mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
- mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+ mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT),
+ mTimestampBase(TIMESTAMP_BASE_DEFAULT) {
}
OutputConfiguration::OutputConfiguration(const android::Parcel& parcel) :
@@ -188,6 +193,12 @@
return err;
}
+ int timestampBase = TIMESTAMP_BASE_DEFAULT;
+ if ((err = parcel->readInt32(×tampBase)) != OK) {
+ ALOGE("%s: Failed to read timestamp base from parcel", __FUNCTION__);
+ return err;
+ }
+
mRotation = rotation;
mSurfaceSetID = setID;
mSurfaceType = surfaceType;
@@ -197,6 +208,7 @@
mIsShared = isShared != 0;
mIsMultiResolution = isMultiResolution != 0;
mStreamUseCase = streamUseCase;
+ mTimestampBase = timestampBase;
for (auto& surface : surfaceShims) {
ALOGV("%s: OutputConfiguration: %p, name %s", __FUNCTION__,
surface.graphicBufferProducer.get(),
@@ -208,9 +220,9 @@
mDynamicRangeProfile = dynamicProfile;
ALOGV("%s: OutputConfiguration: rotation = %d, setId = %d, surfaceType = %d,"
- " physicalCameraId = %s, isMultiResolution = %d, streamUseCase = %d", __FUNCTION__,
- mRotation, mSurfaceSetID, mSurfaceType, String8(mPhysicalCameraId).string(),
- mIsMultiResolution, mStreamUseCase);
+ " physicalCameraId = %s, isMultiResolution = %d, streamUseCase = %d, timestampBase = %d",
+ __FUNCTION__, mRotation, mSurfaceSetID, mSurfaceType,
+ String8(mPhysicalCameraId).string(), mIsMultiResolution, mStreamUseCase, timestampBase);
return err;
}
@@ -227,6 +239,7 @@
mIsMultiResolution = false;
mDynamicRangeProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
mStreamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
+ mTimestampBase = TIMESTAMP_BASE_DEFAULT;
}
OutputConfiguration::OutputConfiguration(
@@ -237,7 +250,8 @@
mWidth(width), mHeight(height), mIsDeferred(false), mIsShared(isShared),
mPhysicalCameraId(physicalCameraId), mIsMultiResolution(false),
mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
- mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) { }
+ mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT),
+ mTimestampBase(TIMESTAMP_BASE_DEFAULT) { }
status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
@@ -290,6 +304,9 @@
err = parcel->writeInt32(mStreamUseCase);
if (err != OK) return err;
+ err = parcel->writeInt32(mTimestampBase);
+ if (err != OK) return err;
+
return OK;
}
diff --git a/camera/include/camera/camera2/OutputConfiguration.h b/camera/include/camera/camera2/OutputConfiguration.h
index f1cb6bd..9a91cc0 100644
--- a/camera/include/camera/camera2/OutputConfiguration.h
+++ b/camera/include/camera/camera2/OutputConfiguration.h
@@ -38,6 +38,14 @@
SURFACE_TYPE_SURFACE_VIEW = 0,
SURFACE_TYPE_SURFACE_TEXTURE = 1
};
+ enum TimestampBaseByte {
+ TIMESTAMP_BASE_DEFAULT = 0,
+ TIMESTAMP_BASE_SENSOR = 1,
+ TIMESTAMP_BASE_MONOTONIC = 2,
+ TIMESTAMP_BASE_REALTIME = 3,
+ TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED = 4
+ };
+
const std::vector<sp<IGraphicBufferProducer>>& getGraphicBufferProducers() const;
int getRotation() const;
int getSurfaceSetID() const;
@@ -50,6 +58,7 @@
String16 getPhysicalCameraId() const;
bool isMultiResolution() const;
int getStreamUseCase() const;
+ int getTimestampBase() const;
// set of sensor pixel mode resolutions allowed {MAX_RESOLUTION, DEFAULT_MODE};
const std::vector<int32_t>& getSensorPixelModesUsed() const;
@@ -93,7 +102,8 @@
mIsMultiResolution == other.mIsMultiResolution &&
sensorPixelModesUsedEqual(other) &&
mDynamicRangeProfile == other.mDynamicRangeProfile &&
- mStreamUseCase == other.mStreamUseCase );
+ mStreamUseCase == other.mStreamUseCase &&
+ mTimestampBase == other.mTimestampBase);
}
bool operator != (const OutputConfiguration& other) const {
return !(*this == other);
@@ -136,6 +146,9 @@
if (mStreamUseCase != other.mStreamUseCase) {
return mStreamUseCase < other.mStreamUseCase;
}
+ if (mTimestampBase != other.mTimestampBase) {
+ return mTimestampBase < other.mTimestampBase;
+ }
return gbpsLessThan(other);
}
@@ -162,6 +175,7 @@
std::vector<int32_t> mSensorPixelModesUsed;
int mDynamicRangeProfile;
int mStreamUseCase;
+ int mTimestampBase;
};
} // namespace params
} // namespace camera2
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index eee7f7e..7b273ec 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -61,8 +61,7 @@
status_t AudioEffect::set(const effect_uuid_t *type,
const effect_uuid_t *uuid,
int32_t priority,
- effect_callback_t cbf,
- void* user,
+ const wp<IAudioEffectCallback>& callback,
audio_session_t sessionId,
audio_io_handle_t io,
const AudioDeviceTypeAddr& device,
@@ -73,7 +72,7 @@
sp<IMemory> cblk;
int enabled;
- ALOGV("set %p mUserData: %p uuid: %p timeLow %08x", this, user, type, type ? type->timeLow : 0);
+ ALOGV("set %p uuid: %p timeLow %08x", this, type, type ? type->timeLow : 0);
if (mIEffect != 0) {
ALOGW("Effect already in use");
@@ -96,9 +95,8 @@
}
mProbe = probe;
mPriority = priority;
- mCbf = cbf;
- mUserData = user;
mSessionId = sessionId;
+ mCallback = callback;
memset(&mDescriptor, 0, sizeof(effect_descriptor_t));
mDescriptor.type = *(type != NULL ? type : EFFECT_UUID_NULL);
@@ -187,11 +185,60 @@
return mStatus;
}
+namespace {
+class LegacyCallbackWrapper : public AudioEffect::IAudioEffectCallback {
+ public:
+ LegacyCallbackWrapper(AudioEffect::legacy_callback_t callback, void* user):
+ mCallback(callback), mUser(user) {}
+ private:
+ void onControlStatusChanged(bool isGranted) override {
+ mCallback(AudioEffect::EVENT_CONTROL_STATUS_CHANGED, mUser, &isGranted);
+ }
+
+ void onEnableStatusChanged(bool isEnabled) override {
+ mCallback(AudioEffect::EVENT_ENABLE_STATUS_CHANGED, mUser, &isEnabled);
+ }
+
+ void onParameterChanged(std::vector<uint8_t> param) override {
+ mCallback(AudioEffect::EVENT_PARAMETER_CHANGED, mUser, param.data());
+ }
+
+ void onError(status_t errorCode) override {
+ mCallback(AudioEffect::EVENT_ERROR, mUser, &errorCode);
+ }
+
+ void onFramesProcessed(int32_t framesProcessed) override {
+ mCallback(AudioEffect::EVENT_FRAMES_PROCESSED, mUser, &framesProcessed);
+ }
+
+ const AudioEffect::legacy_callback_t mCallback;
+ void* const mUser;
+};
+} // namespace
+
+status_t AudioEffect::set(const effect_uuid_t *type,
+ const effect_uuid_t *uuid,
+ int32_t priority,
+ legacy_callback_t cbf,
+ void* user,
+ audio_session_t sessionId,
+ audio_io_handle_t io,
+ const AudioDeviceTypeAddr& device,
+ bool probe,
+ bool notifyFramesProcessed)
+{
+ if (cbf != nullptr) {
+ mLegacyWrapper = sp<LegacyCallbackWrapper>::make(cbf, user);
+ } else if (user != nullptr) {
+ LOG_ALWAYS_FATAL("%s: User provided without callback", __func__);
+ }
+ return set(type, uuid, priority, mLegacyWrapper, sessionId, io, device, probe,
+ notifyFramesProcessed);
+}
status_t AudioEffect::set(const char *typeStr,
const char *uuidStr,
int32_t priority,
- effect_callback_t cbf,
- void* user,
+ const wp<IAudioEffectCallback>& callback,
audio_session_t sessionId,
audio_io_handle_t io,
const AudioDeviceTypeAddr& device,
@@ -213,11 +260,29 @@
pUuid = &uuid;
}
- return set(pType, pUuid, priority, cbf, user, sessionId, io,
+ return set(pType, pUuid, priority, callback, sessionId, io,
device, probe, notifyFramesProcessed);
}
-
+status_t AudioEffect::set(const char *typeStr,
+ const char *uuidStr,
+ int32_t priority,
+ legacy_callback_t cbf,
+ void* user,
+ audio_session_t sessionId,
+ audio_io_handle_t io,
+ const AudioDeviceTypeAddr& device,
+ bool probe,
+ bool notifyFramesProcessed)
+{
+ if (cbf != nullptr) {
+ mLegacyWrapper = sp<LegacyCallbackWrapper>::make(cbf, user);
+ } else if (user != nullptr) {
+ LOG_ALWAYS_FATAL("%s: User provided without callback", __func__);
+ }
+ return set(typeStr, uuidStr, priority, mLegacyWrapper, sessionId, io, device, probe,
+ notifyFramesProcessed);
+}
AudioEffect::~AudioEffect()
{
ALOGV("Destructor %p", this);
@@ -471,9 +536,9 @@
{
ALOGW("IEffect died");
mStatus = DEAD_OBJECT;
- if (mCbf != NULL) {
- status_t status = DEAD_OBJECT;
- mCbf(EVENT_ERROR, mUserData, &status);
+ auto cb = mCallback.promote();
+ if (cb != nullptr) {
+ cb->onError(mStatus);
}
mIEffect.clear();
}
@@ -482,8 +547,8 @@
void AudioEffect::controlStatusChanged(bool controlGranted)
{
- ALOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf,
- mUserData);
+ auto cb = mCallback.promote();
+ ALOGV("controlStatusChanged %p control %d callback %p", this, controlGranted, cb.get());
if (controlGranted) {
if (mStatus == ALREADY_EXISTS) {
mStatus = NO_ERROR;
@@ -493,18 +558,19 @@
mStatus = ALREADY_EXISTS;
}
}
- if (mCbf != NULL) {
- mCbf(EVENT_CONTROL_STATUS_CHANGED, mUserData, &controlGranted);
+ if (cb != nullptr) {
+ cb->onControlStatusChanged(controlGranted);
}
}
void AudioEffect::enableStatusChanged(bool enabled)
{
- ALOGV("enableStatusChanged %p enabled %d mCbf %p", this, enabled, mCbf);
+ auto cb = mCallback.promote();
+ ALOGV("enableStatusChanged %p enabled %d mCallback %p", this, enabled, cb.get());
if (mStatus == ALREADY_EXISTS) {
mEnabled = enabled;
- if (mCbf != NULL) {
- mCbf(EVENT_ENABLE_STATUS_CHANGED, mUserData, &enabled);
+ if (cb != nullptr) {
+ cb->onEnableStatusChanged(enabled);
}
}
}
@@ -516,19 +582,20 @@
if (cmdData.empty() || replyData.empty()) {
return;
}
-
- if (mCbf != NULL && cmdCode == EFFECT_CMD_SET_PARAM) {
+ auto cb = mCallback.promote();
+ if (cb != nullptr && cmdCode == EFFECT_CMD_SET_PARAM) {
std::vector<uint8_t> cmdDataCopy(cmdData);
effect_param_t* cmd = reinterpret_cast<effect_param_t *>(cmdDataCopy.data());
cmd->status = *reinterpret_cast<const int32_t *>(replyData.data());
- mCbf(EVENT_PARAMETER_CHANGED, mUserData, cmd);
+ cb->onParameterChanged(std::move(cmdDataCopy));
}
}
void AudioEffect::framesProcessed(int32_t frames)
{
- if (mCbf != NULL) {
- mCbf(EVENT_FRAMES_PROCESSED, mUserData, &frames);
+ auto cb = mCallback.promote();
+ if (cb != nullptr) {
+ cb->onFramesProcessed(frames);
}
}
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index de14e1c..4bc61f5 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -537,6 +537,8 @@
float maxRequiredSpeed,
audio_port_handle_t selectedDeviceId)
{
+ LOG_ALWAYS_FATAL_IF(mInitialized, "%s: should not be called twice", __func__);
+ mInitialized = true;
status_t status;
uint32_t channelCount;
pid_t callingPid;
@@ -1591,12 +1593,12 @@
status_t AudioTrack::setMarkerPosition(uint32_t marker)
{
+ AutoMutex lock(mLock);
// The only purpose of setting marker position is to get a callback
- if (!mCallback.promote() || isOffloadedOrDirect()) {
+ if (!mCallback.promote() || isOffloadedOrDirect_l()) {
return INVALID_OPERATION;
}
- AutoMutex lock(mLock);
mMarkerPosition = marker;
mMarkerReached = false;
@@ -1624,12 +1626,12 @@
status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod)
{
+ AutoMutex lock(mLock);
// The only purpose of setting position update period is to get a callback
- if (!mCallback.promote() || isOffloadedOrDirect()) {
+ if (!mCallback.promote() || isOffloadedOrDirect_l()) {
return INVALID_OPERATION;
}
- AutoMutex lock(mLock);
mNewPosition = updateAndGetPosition_l() + updatePeriod;
mUpdatePeriod = updatePeriod;
diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
index ee262f3..56884a3 100644
--- a/media/libaudioclient/include/media/AudioEffect.h
+++ b/media/libaudioclient/include/media/AudioEffect.h
@@ -277,7 +277,7 @@
static status_t removeStreamDefaultEffect(audio_unique_id_t id);
/*
- * Events used by callback function (effect_callback_t).
+ * Events used by callback function (legacy_callback_t).
*/
enum event_type {
EVENT_CONTROL_STATUS_CHANGED = 0,
@@ -287,6 +287,47 @@
EVENT_FRAMES_PROCESSED = 4,
};
+ class IAudioEffectCallback : public virtual RefBase {
+ friend AudioEffect;
+ protected:
+ /* The event is received when an application loses or
+ * gains the control of the effect engine. Loss of control happens
+ * if another application requests the use of the engine by creating an AudioEffect for
+ * the same effect type but with a higher priority. Control is returned when the
+ * application having the control deletes its AudioEffect object.
+ * @param isGranted: True if control has been granted. False if stolen.
+ */
+ virtual void onControlStatusChanged([[maybe_unused]] bool isGranted) {}
+
+ /* The event is received by all applications not having the
+ * control of the effect engine when the effect is enabled or disabled.
+ * @param isEnabled: True if enabled. False if disabled.
+ */
+ virtual void onEnableStatusChanged([[maybe_unused]] bool isEnabled) {}
+
+ /* The event is received by all applications not having the
+ * control of the effect engine when an effect parameter is changed.
+ * @param param: A vector containing the raw bytes of a effect_param_type containing
+ * raw data representing a param type, value pair.
+ */
+ // TODO pass an AIDL parcel instead of effect_param_type
+ virtual void onParameterChanged([[maybe_unused]] std::vector<uint8_t> param) {}
+
+ /* The event is received when the binder connection to the mediaserver
+ * is no longer valid. Typically the server has been killed.
+ * @param errorCode: A code representing the type of error.
+ */
+ virtual void onError([[maybe_unused]] status_t errorCode) {}
+
+
+ /* The event is received when the audio server has processed a block of
+ * data.
+ * @param framesProcessed: The number of frames the audio server has
+ * processed.
+ */
+ virtual void onFramesProcessed([[maybe_unused]] int32_t framesProcessed) {}
+ };
+
/* Callback function notifying client application of a change in effect engine state or
* configuration.
* An effect engine can be shared by several applications but only one has the control
@@ -315,7 +356,7 @@
* - EVENT_ERROR: status_t indicating the error (DEAD_OBJECT when media server dies).
*/
- typedef void (*effect_callback_t)(int32_t event, void* user, void *info);
+ typedef void (*legacy_callback_t)(int32_t event, void* user, void *info);
/* Constructor.
@@ -360,7 +401,7 @@
* priority: requested priority for effect control: the priority level corresponds to the
* value of priority parameter: negative values indicate lower priorities, positive values
* higher priorities, 0 being the normal priority.
- * cbf: optional callback function (see effect_callback_t)
+ * cbf: optional callback function (see legacy_callback_t)
* user: pointer to context for use by the callback receiver.
* sessionId: audio session this effect is associated to.
* If equal to AUDIO_SESSION_OUTPUT_MIX, the effect will be global to
@@ -383,10 +424,20 @@
* - NO_INIT: audio flinger or audio hardware not initialized
*/
status_t set(const effect_uuid_t *type,
- const effect_uuid_t *uuid = NULL,
+ const effect_uuid_t *uuid = nullptr,
int32_t priority = 0,
- effect_callback_t cbf = NULL,
- void* user = NULL,
+ const wp<IAudioEffectCallback>& callback = nullptr,
+ audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
+ audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
+ const AudioDeviceTypeAddr& device = {},
+ bool probe = false,
+ bool notifyFramesProcessed = false);
+
+ status_t set(const effect_uuid_t *type,
+ const effect_uuid_t *uuid,
+ int32_t priority,
+ legacy_callback_t cbf,
+ void* user,
audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
const AudioDeviceTypeAddr& device = {},
@@ -396,10 +447,21 @@
* Same as above but with type and uuid specified by character strings.
*/
status_t set(const char *typeStr,
- const char *uuidStr = NULL,
+ const char *uuidStr = nullptr,
int32_t priority = 0,
- effect_callback_t cbf = NULL,
- void* user = NULL,
+ const wp<IAudioEffectCallback>& callback = nullptr,
+ audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
+ audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
+ const AudioDeviceTypeAddr& device = {},
+ bool probe = false,
+ bool notifyFramesProcessed = false);
+
+
+ status_t set(const char *typeStr,
+ const char *uuidStr,
+ int32_t priority,
+ legacy_callback_t cbf,
+ void* user,
audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
const AudioDeviceTypeAddr& device = {},
@@ -535,18 +597,19 @@
protected:
android::content::AttributionSourceState mClientAttributionSource; // source for app op checks.
- bool mEnabled = false; // enable state
- audio_session_t mSessionId = AUDIO_SESSION_OUTPUT_MIX; // audio session ID
- int32_t mPriority = 0; // priority for effect control
- status_t mStatus = NO_INIT; // effect status
- bool mProbe = false; // effect created in probe mode: all commands
- // are no ops because mIEffect is NULL
- effect_callback_t mCbf = nullptr; // callback function for status, control and
- // parameter changes notifications
- void* mUserData = nullptr;// client context for callback function
- effect_descriptor_t mDescriptor = {}; // effect descriptor
- int32_t mId = -1; // system wide unique effect engine instance ID
- Mutex mLock; // Mutex for mEnabled access
+ bool mEnabled = false; // enable state
+ audio_session_t mSessionId = AUDIO_SESSION_OUTPUT_MIX; // audio session ID
+ int32_t mPriority = 0; // priority for effect control
+ status_t mStatus = NO_INIT; // effect status
+ bool mProbe = false; // effect created in probe mode: all commands
+ // are no ops because mIEffect is nullptr
+
+ wp<IAudioEffectCallback> mCallback = nullptr; // callback interface for status, control and
+ // parameter changes notifications
+ sp<IAudioEffectCallback> mLegacyWrapper = nullptr;
+ effect_descriptor_t mDescriptor = {}; // effect descriptor
+ int32_t mId = -1; // system wide unique effect engine instance ID
+ Mutex mLock; // Mutex for mEnabled access
// IEffectClient
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 16e10b5..153d4b5 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -1348,6 +1348,7 @@
sp<IAudioTrackCallback> mLegacyCallbackWrapper; // wrapper for legacy callback interface
// for notification APIs
+ bool mInitialized = false; // Set after track is initialized
// next 2 fields are const after constructor or set()
uint32_t mNotificationFramesReq; // requested number of frames between each
// notification callback,
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index f50acae..f7bc177 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -178,10 +178,6 @@
"NdkMediaDataSourceCallbacks.cpp",
],
- include_dirs: [
- "frameworks/av/media/libstagefright/include",
- "frameworks/av/media/ndk/include",
- ],
export_include_dirs: [
"include",
@@ -194,6 +190,7 @@
],
header_libs: [
+ "libstagefright_headers",
"libmedia_headers",
],
@@ -224,6 +221,7 @@
"libcutils",
"android.hardware.graphics.bufferqueue@1.0",
],
+
header_libs: [
"libstagefright_foundation_headers",
],
@@ -231,9 +229,6 @@
cflags: [
"-D__ANDROID_VNDK__",
],
- include_dirs: [
- "frameworks/av/media/ndk/",
- ],
}
cc_library_static {
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index 0e2de4e..227459a 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -158,8 +158,7 @@
}
Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
- if (mCodec->mAsyncCallbackUserData != NULL
- || mCodec->mAsyncCallback.onAsyncInputAvailable != NULL) {
+ if (mCodec->mAsyncCallback.onAsyncInputAvailable != NULL) {
mCodec->mAsyncCallback.onAsyncInputAvailable(
mCodec,
mCodec->mAsyncCallbackUserData,
@@ -205,8 +204,7 @@
(uint32_t)flags};
Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
- if (mCodec->mAsyncCallbackUserData != NULL
- || mCodec->mAsyncCallback.onAsyncOutputAvailable != NULL) {
+ if (mCodec->mAsyncCallback.onAsyncOutputAvailable != NULL) {
mCodec->mAsyncCallback.onAsyncOutputAvailable(
mCodec,
mCodec->mAsyncCallbackUserData,
@@ -234,8 +232,7 @@
AMediaFormat *aMediaFormat = AMediaFormat_fromMsg(©);
Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
- if (mCodec->mAsyncCallbackUserData != NULL
- || mCodec->mAsyncCallback.onAsyncFormatChanged != NULL) {
+ if (mCodec->mAsyncCallback.onAsyncFormatChanged != NULL) {
mCodec->mAsyncCallback.onAsyncFormatChanged(
mCodec,
mCodec->mAsyncCallbackUserData,
@@ -263,8 +260,7 @@
err, actionCode, detail.c_str());
Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
- if (mCodec->mAsyncCallbackUserData != NULL
- || mCodec->mAsyncCallback.onAsyncError != NULL) {
+ if (mCodec->mAsyncCallback.onAsyncError != NULL) {
mCodec->mAsyncCallback.onAsyncError(
mCodec,
mCodec->mAsyncCallbackUserData,
@@ -474,16 +470,20 @@
AMediaCodec *mData,
AMediaCodecOnAsyncNotifyCallback callback,
void *userdata) {
- if (mData->mAsyncNotify == NULL && userdata != NULL) {
- mData->mAsyncNotify = new AMessage(kWhatAsyncNotify, mData->mHandler);
- status_t err = mData->mCodec->setCallback(mData->mAsyncNotify);
- if (err != OK) {
- ALOGE("setAsyncNotifyCallback: err(%d), failed to set async callback", err);
- return translate_error(err);
- }
- }
Mutex::Autolock _l(mData->mAsyncCallbackLock);
+
+ if (mData->mAsyncNotify == NULL) {
+ mData->mAsyncNotify = new AMessage(kWhatAsyncNotify, mData->mHandler);
+ }
+
+ // always call, codec may have been reset/re-configured since last call.
+ status_t err = mData->mCodec->setCallback(mData->mAsyncNotify);
+ if (err != OK) {
+ ALOGE("setAsyncNotifyCallback: err(%d), failed to set async callback", err);
+ return translate_error(err);
+ }
+
mData->mAsyncCallback = callback;
mData->mAsyncCallbackUserData = userdata;
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 11fa991..d26b730 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -861,6 +861,7 @@
bool isMultiResolution = outputConfiguration.isMultiResolution();
int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
int streamUseCase = outputConfiguration.getStreamUseCase();
+ int timestampBase = outputConfiguration.getTimestampBase();
res = SessionConfigurationUtils::checkSurfaceType(numBufferProducers, deferredConsumer,
outputConfiguration.getSurfaceType());
@@ -905,7 +906,7 @@
res = SessionConfigurationUtils::createSurfaceFromGbp(streamInfo,
isStreamInfoValid, surface, bufferProducer, mCameraIdStr,
mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
- streamUseCase);
+ streamUseCase, timestampBase);
if (!res.isOk())
return res;
@@ -951,7 +952,8 @@
static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
&streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution,
- /*consumerUsage*/0, streamInfo.dynamicRangeProfile, streamInfo.streamUseCase);
+ /*consumerUsage*/0, streamInfo.dynamicRangeProfile, streamInfo.streamUseCase,
+ streamInfo.timestampBase);
}
if (err != OK) {
@@ -1062,7 +1064,8 @@
std::forward_as_tuple(width, height, format, dataSpace, consumerUsage,
overriddenSensorPixelModesUsed,
outputConfiguration.getDynamicRangeProfile(),
- outputConfiguration.getStreamUseCase()));
+ outputConfiguration.getStreamUseCase(),
+ outputConfiguration.getTimestampBase()));
ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
" (%d x %d) stream with format 0x%x.",
@@ -1251,7 +1254,7 @@
const std::vector<int32_t> &sensorPixelModesUsed =
outputConfiguration.getSensorPixelModesUsed();
int streamUseCase = outputConfiguration.getStreamUseCase();
-
+ int timestampBase = outputConfiguration.getTimestampBase();
int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
for (size_t i = 0; i < newOutputsMap.size(); i++) {
@@ -1260,7 +1263,7 @@
res = SessionConfigurationUtils::createSurfaceFromGbp(outInfo,
/*isStreamInfoValid*/ false, surface, newOutputsMap.valueAt(i), mCameraIdStr,
mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
- streamUseCase);
+ streamUseCase, timestampBase);
if (!res.isOk())
return res;
@@ -1619,6 +1622,7 @@
outputConfiguration.getSensorPixelModesUsed();
int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
int streamUseCase= outputConfiguration.getStreamUseCase();
+ int timestampBase = outputConfiguration.getTimestampBase();
for (auto& bufferProducer : bufferProducers) {
// Don't create multiple streams for the same target surface
ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
@@ -1632,7 +1636,7 @@
res = SessionConfigurationUtils::createSurfaceFromGbp(mStreamInfoMap[streamId],
true /*isStreamInfoValid*/, surface, bufferProducer, mCameraIdStr,
mDevice->infoPhysical(physicalId), sensorPixelModesUsed, dynamicRangeProfile,
- streamUseCase);
+ streamUseCase, timestampBase);
if (!res.isOk())
return res;
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 6ddf500..baa21f0 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -184,7 +184,8 @@
bool isShared = false, bool isMultiResolution = false,
uint64_t consumerUsage = 0,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) = 0;
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT) = 0;
/**
* Create an output stream of the requested size, format, rotation and
@@ -203,7 +204,8 @@
bool isShared = false, bool isMultiResolution = false,
uint64_t consumerUsage = 0,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) = 0;
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT) = 0;
/**
* Create an input stream of width, height, and format.
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index c8f6310..f31241c 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -86,6 +86,7 @@
mStatusWaiters(0),
mUsePartialResult(false),
mNumPartialResults(1),
+ mDeviceTimeBaseIsRealtime(false),
mTimestampOffset(0),
mNextResultFrameNumber(0),
mNextReprocessResultFrameNumber(0),
@@ -189,11 +190,12 @@
mIsInputStreamMultiResolution = false;
// Measure the clock domain offset between camera and video/hw_composer
+ mTimestampOffset = getMonoToBoottimeOffset();
camera_metadata_entry timestampSource =
mDeviceInfo.find(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE);
if (timestampSource.count > 0 && timestampSource.data.u8[0] ==
ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME) {
- mTimestampOffset = getMonoToBoottimeOffset();
+ mDeviceTimeBaseIsRealtime = true;
}
// Will the HAL be sending in early partial result metadata?
@@ -978,7 +980,7 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
- uint64_t consumerUsage, int dynamicRangeProfile, int streamUseCase) {
+ uint64_t consumerUsage, int dynamicRangeProfile, int streamUseCase, int timestampBase) {
ATRACE_CALL();
if (consumer == nullptr) {
@@ -992,7 +994,7 @@
return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
format, dataSpace, rotation, id, physicalCameraId, sensorPixelModesUsed, surfaceIds,
streamSetId, isShared, isMultiResolution, consumerUsage, dynamicRangeProfile,
- streamUseCase);
+ streamUseCase, timestampBase);
}
static bool isRawFormat(int format) {
@@ -1012,16 +1014,18 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
const String8& physicalCameraId, const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
- uint64_t consumerUsage, int dynamicRangeProfile, int streamUseCase) {
+ uint64_t consumerUsage, int dynamicRangeProfile, int streamUseCase, int timestampBase) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Mutex::Autolock l(mLock);
ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
- " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d",
+ " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d"
+ " dynamicRangeProfile %d, streamUseCase %d, timestampBase %d",
mId.string(), mNextStreamId, width, height, format, dataSpace, rotation,
- consumerUsage, isShared, physicalCameraId.string(), isMultiResolution);
+ consumerUsage, isShared, physicalCameraId.string(), isMultiResolution,
+ dynamicRangeProfile, streamUseCase, timestampBase);
status_t res;
bool wasActive = false;
@@ -1090,7 +1094,8 @@
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, blobBufferSize, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile, streamUseCase);
+ isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
+ timestampBase);
} else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
bool maxResolution =
sensorPixelModesUsed.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
@@ -1104,22 +1109,26 @@
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile, streamUseCase);
+ isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
+ timestampBase);
} else if (isShared) {
newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- mUseHalBufManager, dynamicRangeProfile, streamUseCase);
+ mUseHalBufManager, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
+ timestampBase);
} else if (consumers.size() == 0 && hasDeferredConsumer) {
newStream = new Camera3OutputStream(mNextStreamId,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile, streamUseCase);
+ isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
+ timestampBase);
} else {
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile, streamUseCase);
+ isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
+ timestampBase);
}
size_t consumerCount = consumers.size();
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index d466ae4..0f5e65b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -135,7 +135,8 @@
uint64_t consumerUsage = 0,
int dynamicRangeProfile =
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) override;
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT) override;
status_t createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
@@ -148,7 +149,8 @@
uint64_t consumerUsage = 0,
int dynamicRangeProfile =
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) override;
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT) override;
status_t createInputStream(
uint32_t width, uint32_t height, int format, bool isMultiResolution,
@@ -526,6 +528,7 @@
/**** End scope for mLock ****/
+ bool mDeviceTimeBaseIsRealtime;
// The offset converting from clock domain of other subsystem
// (video/hardware composer) to that of camera. Assumption is that this
// offset won't change during the life cycle of the camera device. In other
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index dc3a6f3..f737ed6 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -34,11 +34,12 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution, int dynamicRangeProfile, int streamUseCase) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile, int streamUseCase,
+ bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3Stream(id, type,
width, height, maxSize, format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile, streamUseCase),
+ dynamicRangeProfile, streamUseCase, deviceTimeBaseIsRealtime, timestampBase),
mTotalBufferCount(0),
mHandoutTotalBufferCount(0),
mHandoutOutputBufferCount(0),
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index f2b1536..300f207 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -39,7 +39,9 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
public:
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 95d19ec..a82d19b 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -47,11 +47,12 @@
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int dynamicRangeProfile,
- int streamUseCase) :
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile, streamUseCase),
+ dynamicRangeProfile, streamUseCase, deviceTimeBaseIsRealtime,
+ timestampBase),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
@@ -77,14 +78,14 @@
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int dynamicRangeProfile,
- int streamUseCase) :
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height, maxSize,
format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
- setId, isMultiResolution, dynamicRangeProfile, streamUseCase),
+ setId, isMultiResolution, dynamicRangeProfile, streamUseCase,
+ deviceTimeBaseIsRealtime, timestampBase),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
- mUseMonoTimestamp(false),
mUseBufferManager(false),
mTimestampOffset(timestampOffset),
mConsumerUsage(0),
@@ -113,11 +114,12 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int dynamicRangeProfile,
- int streamUseCase) :
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile, streamUseCase),
+ dynamicRangeProfile, streamUseCase, deviceTimeBaseIsRealtime,
+ timestampBase),
mConsumer(nullptr),
mTransform(0),
mTraceFirstBuffer(true),
@@ -152,18 +154,19 @@
android_dataspace dataSpace,
camera_stream_rotation_t rotation,
const String8& physicalCameraId,
- const std::unordered_set<int32_t> &sensorPixelModesUsed,
+ const std::unordered_set<int32_t> &sensorPixelModesUsed,
uint64_t consumerUsage, nsecs_t timestampOffset,
int setId, bool isMultiResolution,
- int dynamicRangeProfile, int streamUseCase) :
+ int dynamicRangeProfile, int streamUseCase,
+ bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3IOStreamBase(id, type, width, height,
/*maxSize*/0,
format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile, streamUseCase),
+ dynamicRangeProfile, streamUseCase, deviceTimeBaseIsRealtime,
+ timestampBase),
mTransform(0),
mTraceFirstBuffer(true),
- mUseMonoTimestamp(false),
mUseBufferManager(false),
mTimestampOffset(timestampOffset),
mConsumerUsage(consumerUsage),
@@ -365,13 +368,10 @@
dumpImageToDisk(timestamp, anwBuffer, anwReleaseFence);
}
- /* Certain consumers (such as AudioSource or HardwareComposer) use
- * MONOTONIC time, causing time misalignment if camera timestamp is
- * in BOOTTIME. Do the conversion if necessary. */
nsecs_t t = mPreviewFrameScheduler != nullptr ? readoutTimestamp : timestamp;
- nsecs_t adjustedTs = mUseMonoTimestamp ? t - mTimestampOffset : t;
+ t -= mTimestampOffset;
if (mPreviewFrameScheduler != nullptr) {
- res = mPreviewFrameScheduler->queuePreviewBuffer(adjustedTs, transform,
+ res = mPreviewFrameScheduler->queuePreviewBuffer(t, transform,
anwBuffer, anwReleaseFence);
if (res != OK) {
ALOGE("%s: Stream %d: Error queuing buffer to preview buffer scheduler: %s (%d)",
@@ -380,7 +380,7 @@
}
} else {
setTransform(transform);
- res = native_window_set_buffers_timestamp(mConsumer.get(), adjustedTs);
+ res = native_window_set_buffers_timestamp(mConsumer.get(), t);
if (res != OK) {
ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)",
__FUNCTION__, mId, strerror(-res), res);
@@ -572,10 +572,18 @@
}
mTotalBufferCount = maxConsumerBuffers + camera_stream::max_buffers;
- if (allowPreviewScheduler && isConsumedByHWComposer()) {
+
+ int timestampBase = getTimestampBase();
+ bool isDefaultTimeBase = (timestampBase ==
+ OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
+ if (allowPreviewScheduler) {
// We cannot distinguish between a SurfaceView and an ImageReader of
// preview buffer format. The PreviewFrameScheduler needs to handle both.
- if (!property_get_bool("camera.disable_preview_scheduler", false)) {
+ bool forceChoreographer = (timestampBase ==
+ OutputConfiguration::TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED);
+ bool defaultToChoreographer = (isDefaultTimeBase && isConsumedByHWComposer() &&
+ !property_get_bool("camera.disable_preview_scheduler", false));
+ if (forceChoreographer || defaultToChoreographer) {
mPreviewFrameScheduler = std::make_unique<PreviewFrameScheduler>(*this, mConsumer);
mTotalBufferCount += PreviewFrameScheduler::kQueueDepthWatermark;
}
@@ -584,7 +592,27 @@
mHandoutTotalBufferCount = 0;
mFrameCount = 0;
mLastTimestamp = 0;
- mUseMonoTimestamp = (isConsumedByHWComposer() || isVideoStream());
+
+ if (isDeviceTimeBaseRealtime()) {
+ if (isDefaultTimeBase && !isConsumedByHWComposer() && !isVideoStream()) {
+ // Default time base, but not hardware composer or video encoder
+ mTimestampOffset = 0;
+ } else if (timestampBase == OutputConfiguration::TIMESTAMP_BASE_REALTIME ||
+ timestampBase == OutputConfiguration::TIMESTAMP_BASE_SENSOR) {
+ mTimestampOffset = 0;
+ }
+ // If timestampBase is CHOREOGRAPHER SYNCED or MONOTONIC, leave
+ // timestamp offset as bootTime - monotonicTime.
+ } else {
+ if (timestampBase == OutputConfiguration::TIMESTAMP_BASE_REALTIME) {
+ // Reverse offset for monotonicTime -> bootTime
+ mTimestampOffset = -mTimestampOffset;
+ } else {
+ // If timestampBase is DEFAULT, MONOTONIC, SENSOR, or
+ // CHOREOGRAPHER_SYNCED, timestamp offset is 0.
+ mTimestampOffset = 0;
+ }
+ }
res = native_window_set_buffer_count(mConsumer.get(),
mTotalBufferCount);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 7d2d32e..c7910b7 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -91,7 +91,9 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
/**
* Set up a stream for formats that have a variable buffer size for the same
* dimensions, such as compressed JPEG.
@@ -105,7 +107,9 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
/**
* Set up a stream with deferred consumer for formats that have 2 dimensions, such as
* RAW and YUV. The consumer must be set before using this stream for output. A valid
@@ -118,7 +122,9 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
virtual ~Camera3OutputStream();
@@ -247,7 +253,9 @@
uint64_t consumerUsage = 0, nsecs_t timestampOffset = 0,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
/**
* Note that we release the lock briefly in this function
@@ -289,9 +297,6 @@
// Name of Surface consumer
String8 mConsumerName;
- // Whether consumer assumes MONOTONIC timestamp
- bool mUseMonoTimestamp;
-
/**
* GraphicBuffer manager this stream is registered to. Used to replace the buffer
* allocation/deallocation role of BufferQueue.
@@ -310,7 +315,11 @@
bool mUseBufferManager;
/**
- * Timestamp offset for video and hardware composer consumed streams
+ * Offset used to override camera HAL produced timestamps
+ *
+ * The offset is first initialized to bootTime - monotonicTime in
+ * constructor, and may later be updated based on the client's timestampBase
+ * setting.
*/
nsecs_t mTimestampOffset;
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index fbd1e56..047897e 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -34,11 +34,11 @@
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool useHalBufManager, int dynamicProfile,
- int streamUseCase) :
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3OutputStream(id, CAMERA_STREAM_OUTPUT, width, height,
format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
consumerUsage, timestampOffset, setId, /*isMultiResolution*/false,
- dynamicProfile, streamUseCase),
+ dynamicProfile, streamUseCase, deviceTimeBaseIsRealtime, timestampBase),
mUseHalBufManager(useHalBufManager) {
size_t consumerCount = std::min(surfaces.size(), kMaxOutputs);
if (surfaces.size() > consumerCount) {
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index 223d52b..dc22c42 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -42,7 +42,9 @@
int setId = CAMERA3_STREAM_SET_ID_INVALID,
bool useHalBufManager = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
virtual ~Camera3SharedOutputStream();
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 6b093b3..3f0299b 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -55,7 +55,7 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int dynamicRangeProfile,
- int streamUseCase) :
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
camera_stream(),
mId(id),
mSetId(setId),
@@ -80,7 +80,9 @@
mOriginalDataSpace(dataSpace),
mPhysicalCameraId(physicalCameraId),
mLastTimestamp(0),
- mIsMultiResolution(isMultiResolution) {
+ mIsMultiResolution(isMultiResolution),
+ mDeviceTimeBaseIsRealtime(deviceTimeBaseIsRealtime),
+ mTimestampBase(timestampBase) {
camera_stream::stream_type = type;
camera_stream::width = width;
@@ -181,6 +183,14 @@
return camera_stream::use_case;
}
+int Camera3Stream::getTimestampBase() const {
+ return mTimestampBase;
+}
+
+bool Camera3Stream::isDeviceTimeBaseRealtime() const {
+ return mDeviceTimeBaseIsRealtime;
+}
+
void Camera3Stream::setOfflineProcessingSupport(bool support) {
mSupportOfflineProcessing = support;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index ada570b..8232ce0 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -179,6 +179,8 @@
int getMaxHalBuffers() const;
const String8& physicalCameraId() const;
int getStreamUseCase() const;
+ int getTimestampBase() const;
+ bool isDeviceTimeBaseRealtime() const;
void setOfflineProcessingSupport(bool) override;
bool getOfflineProcessingSupport() const override;
@@ -507,7 +509,7 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int dynamicRangeProfile,
- int streamUseCase);
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase);
wp<Camera3StreamBufferFreedListener> mBufferFreedListener;
@@ -630,6 +632,9 @@
bool mIsMultiResolution = false;
bool mSupportOfflineProcessing = false;
+
+ bool mDeviceTimeBaseIsRealtime;
+ int mTimestampBase;
}; // class Camera3Stream
}; // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 7b1597b..8962fac 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -19,6 +19,7 @@
#include <utils/RefBase.h>
+#include <camera/camera2/OutputConfiguration.h>
#include <camera/CameraMetadata.h>
#include "Camera3StreamBufferListener.h"
#include "Camera3StreamBufferFreedListener.h"
@@ -111,18 +112,20 @@
std::unordered_set<int32_t> sensorPixelModesUsed;
int dynamicRangeProfile;
int streamUseCase;
+ int timestampBase;
OutputStreamInfo() :
width(-1), height(-1), format(-1), dataSpace(HAL_DATASPACE_UNKNOWN),
consumerUsage(0),
dynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
- streamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {}
+ streamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT),
+ timestampBase(OutputConfiguration::TIMESTAMP_BASE_DEFAULT) {}
OutputStreamInfo(int _width, int _height, int _format, android_dataspace _dataSpace,
uint64_t _consumerUsage, const std::unordered_set<int32_t>& _sensorPixelModesUsed,
- int _dynamicRangeProfile, int _streamUseCase) :
+ int _dynamicRangeProfile, int _streamUseCase, int _timestampBase) :
width(_width), height(_height), format(_format),
dataSpace(_dataSpace), consumerUsage(_consumerUsage),
sensorPixelModesUsed(_sensorPixelModesUsed), dynamicRangeProfile(_dynamicRangeProfile),
- streamUseCase(_streamUseCase) {}
+ streamUseCase(_streamUseCase), timestampBase(_timestampBase) {}
};
/**
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index 548fb0b..751f24f 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -334,7 +334,7 @@
sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile,
- int streamUseCase) {
+ int streamUseCase, int timestampBase) {
// bufferProducer must be non-null
if (gbp == nullptr) {
String8 msg = String8::format("Camera %s: Surface is NULL", logicalCameraId.string());
@@ -454,6 +454,13 @@
ALOGE("%s: %s", __FUNCTION__, msg.string());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
}
+ if (timestampBase < OutputConfiguration::TIMESTAMP_BASE_DEFAULT ||
+ timestampBase > OutputConfiguration::TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED) {
+ String8 msg = String8::format("Camera %s: invalid timestamp base %d",
+ logicalCameraId.string(), timestampBase);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
if (!isStreamInfoValid) {
streamInfo.width = width;
@@ -464,6 +471,7 @@
streamInfo.sensorPixelModesUsed = overriddenSensorPixelModes;
streamInfo.dynamicRangeProfile = dynamicRangeProfile;
streamInfo.streamUseCase = streamUseCase;
+ streamInfo.timestampBase = timestampBase;
return binder::Status::ok();
}
if (width != streamInfo.width) {
@@ -697,6 +705,7 @@
}
int streamUseCase = it.getStreamUseCase();
+ int timestampBase = it.getTimestampBase();
if (deferredConsumer) {
streamInfo.width = it.getWidth();
streamInfo.height = it.getHeight();
@@ -731,7 +740,7 @@
sp<Surface> surface;
res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile,
- streamUseCase);
+ streamUseCase, timestampBase);
if (!res.isOk())
return res;
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 8dfc11d..3dcbdbc 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -98,7 +98,7 @@
sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile,
- int streamUseCase);
+ int streamUseCase, int timestampBase);
void mapStreamInfo(const camera3::OutputStreamInfo &streamInfo,
camera3::camera_stream_rotation_t rotation, String8 physicalId, int32_t groupId,
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 2a53ef3..3f18b95 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -188,7 +188,8 @@
__func__, audioFormat, getDeviceId(), getSessionId());
// Create MMAP/NOIRQ buffer.
- if (createMmapBuffer(&mAudioDataFileDescriptor) != AAUDIO_OK) {
+ result = createMmapBuffer(&mAudioDataFileDescriptor);
+ if (result != AAUDIO_OK) {
goto error;
}
diff --git a/services/tuner/TunerFilter.cpp b/services/tuner/TunerFilter.cpp
index fb5bfa3..e8c7767 100644
--- a/services/tuner/TunerFilter.cpp
+++ b/services/tuner/TunerFilter.cpp
@@ -337,6 +337,9 @@
}
}
+ if (mFilterCallback != nullptr) {
+ mFilterCallback->detachCallbacks();
+ }
auto res = mFilter->close();
mFilter = nullptr;
mStarted = false;
@@ -470,6 +473,12 @@
}
}
+void TunerFilter::FilterCallback::detachCallbacks() {
+ Mutex::Autolock _l(mCallbackLock);
+ mOriginalCallback = nullptr;
+ mTunerFilterCallback = nullptr;
+}
+
} // namespace tuner
} // namespace tv
} // namespace media
diff --git a/services/tuner/TunerFilter.h b/services/tuner/TunerFilter.h
index 529c191..93d8898 100644
--- a/services/tuner/TunerFilter.h
+++ b/services/tuner/TunerFilter.h
@@ -67,6 +67,7 @@
void sendSharedFilterStatus(int32_t status);
void attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback>& in_cb);
void detachSharedFilterCallback();
+ void detachCallbacks();
private:
shared_ptr<ITunerFilterCallback> mTunerFilterCallback;
diff --git a/services/tuner/hidl/TunerHidlFilter.cpp b/services/tuner/hidl/TunerHidlFilter.cpp
index a5bbf39..6d8ae03 100644
--- a/services/tuner/hidl/TunerHidlFilter.cpp
+++ b/services/tuner/hidl/TunerHidlFilter.cpp
@@ -510,6 +510,9 @@
}
}
+ if (mFilterCallback != nullptr) {
+ mFilterCallback->detachCallbacks();
+ }
HidlResult res = mFilter->close();
mFilter = nullptr;
mFilter_1_1 = nullptr;
@@ -970,6 +973,12 @@
}
}
+void TunerHidlFilter::FilterCallback::detachCallbacks() {
+ Mutex::Autolock _l(mCallbackLock);
+ mOriginalCallback = nullptr;
+ mTunerFilterCallback = nullptr;
+}
+
/////////////// FilterCallback Helper Methods ///////////////////////
void TunerHidlFilter::FilterCallback::getAidlFilterEvent(
const vector<HidlDemuxFilterEvent::Event>& events,
diff --git a/services/tuner/hidl/TunerHidlFilter.h b/services/tuner/hidl/TunerHidlFilter.h
index b8fad22..63c7a1b 100644
--- a/services/tuner/hidl/TunerHidlFilter.h
+++ b/services/tuner/hidl/TunerHidlFilter.h
@@ -129,6 +129,7 @@
void sendSharedFilterStatus(int32_t status);
void attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback>& in_cb);
void detachSharedFilterCallback();
+ void detachCallbacks();
private:
void getAidlFilterEvent(const vector<HidlDemuxFilterEvent::Event>& events,