Merge "Camera: Ensure correct error message for disconnected devices" into nyc-dev
diff --git a/camera/ndk/NdkCameraCaptureSession.cpp b/camera/ndk/NdkCameraCaptureSession.cpp
index ab93bd6..d6eff24 100644
--- a/camera/ndk/NdkCameraCaptureSession.cpp
+++ b/camera/ndk/NdkCameraCaptureSession.cpp
@@ -122,7 +122,16 @@
}
EXPORT
-camera_status_t ACameraCaptureSession_abortCaptures(ACameraCaptureSession*) {
+camera_status_t ACameraCaptureSession_abortCaptures(ACameraCaptureSession* session) {
ATRACE_CALL();
- return ACAMERA_OK;
+ if (session == nullptr) {
+ ALOGE("%s: Error: session is null", __FUNCTION__);
+ return ACAMERA_ERROR_INVALID_PARAMETER;
+ }
+
+ if (session->isClosed()) {
+ ALOGE("%s: session %p is already closed", __FUNCTION__, session);
+ return ACAMERA_ERROR_SESSION_CLOSED;
+ }
+ return session->abortCaptures();
}
diff --git a/camera/ndk/impl/ACameraCaptureSession.cpp b/camera/ndk/impl/ACameraCaptureSession.cpp
index b741e46..b9c159d 100644
--- a/camera/ndk/impl/ACameraCaptureSession.cpp
+++ b/camera/ndk/impl/ACameraCaptureSession.cpp
@@ -90,6 +90,24 @@
}
camera_status_t
+ACameraCaptureSession::abortCaptures() {
+ sp<CameraDevice> dev = getDeviceSp();
+ if (dev == nullptr) {
+ ALOGE("Error: Device associated with session %p has been closed!", this);
+ return ACAMERA_ERROR_SESSION_CLOSED;
+ }
+
+ camera_status_t ret;
+ dev->lockDeviceForSessionOps();
+ {
+ Mutex::Autolock _l(mSessionLock);
+ ret = dev->flushLocked(this);
+ }
+ dev->unlockDevice();
+ return ret;
+}
+
+camera_status_t
ACameraCaptureSession::setRepeatingRequest(
/*optional*/ACameraCaptureSession_captureCallbacks* cbs,
int numRequests, ACaptureRequest** requests,
diff --git a/camera/ndk/impl/ACameraCaptureSession.h b/camera/ndk/impl/ACameraCaptureSession.h
index f20b324..58428e6 100644
--- a/camera/ndk/impl/ACameraCaptureSession.h
+++ b/camera/ndk/impl/ACameraCaptureSession.h
@@ -77,6 +77,8 @@
camera_status_t stopRepeating();
+ camera_status_t abortCaptures();
+
camera_status_t setRepeatingRequest(
/*optional*/ACameraCaptureSession_captureCallbacks* cbs,
int numRequests, ACaptureRequest** requests,
@@ -104,7 +106,6 @@
const wp<CameraDevice> mDevice;
bool mIsClosed = false;
bool mClosedByApp = false;
- bool mIdle = true;
Mutex mSessionLock;
};
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 6bca692..8f1115a 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -170,6 +170,7 @@
// set new session as current session
newSession->incStrong((void *) ACameraDevice_createCaptureSession);
mCurrentSession = newSession;
+ mFlushing = false;
*session = newSession;
return ACAMERA_OK;
}
@@ -389,6 +390,58 @@
}
camera_status_t
+CameraDevice::flushLocked(ACameraCaptureSession* session) {
+ camera_status_t ret = checkCameraClosedOrErrorLocked();
+ if (ret != ACAMERA_OK) {
+ ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
+ return ret;
+ }
+
+ // This should never happen because creating a new session will close
+ // previous one and thus reject any API call from previous session.
+ // But still good to check here in case something unexpected happen.
+ if (session != mCurrentSession) {
+ ALOGE("Camera %s session %p is not current active session!", getId(), session);
+ return ACAMERA_ERROR_INVALID_OPERATION;
+ }
+
+ if (mFlushing) {
+ ALOGW("Camera %s is already aborting captures", getId());
+ return ACAMERA_OK;
+ }
+
+ mFlushing = true;
+ // Send onActive callback to guarantee there is always active->ready transition
+ sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
+ msg->setPointer(kContextKey, session->mUserSessionCallback.context);
+ msg->setObject(kSessionSpKey, session);
+ msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
+ msg->post();
+
+ // If device is already idling, send callback and exit early
+ if (mIdle) {
+ sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
+ msg->setPointer(kContextKey, session->mUserSessionCallback.context);
+ msg->setObject(kSessionSpKey, session);
+ msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
+ msg->post();
+ mFlushing = false;
+ return ACAMERA_OK;
+ }
+
+ int64_t lastFrameNumber;
+ binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
+ if (!remoteRet.isOk()) {
+ ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
+ return ACAMERA_ERROR_UNKNOWN;
+ }
+ if (mRepeatingSequenceId != REQUEST_ID_NONE) {
+ checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
+ }
+ return ACAMERA_OK;
+}
+
+camera_status_t
CameraDevice::waitUntilIdleLocked() {
camera_status_t ret = checkCameraClosedOrErrorLocked();
if (ret != ACAMERA_OK) {
@@ -1109,6 +1162,7 @@
msg->post();
}
dev->mIdle = true;
+ dev->mFlushing = false;
return ret;
}
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 46243b9..fd51a81 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -96,6 +96,8 @@
camera_status_t stopRepeatingLocked();
+ camera_status_t flushLocked(ACameraCaptureSession*);
+
camera_status_t waitUntilIdleLocked();
@@ -152,13 +154,13 @@
std::atomic_bool mClosing;
inline bool isClosed() { return mClosing; }
- bool mInError;
- camera_status_t mError;
+ bool mInError = false;
+ camera_status_t mError = ACAMERA_OK;
void onCaptureErrorLocked(
int32_t errorCode,
const CaptureResultExtras& resultExtras);
- bool mIdle;
+ bool mIdle = true;
// This will avoid a busy session being deleted before it's back to idle state
sp<ACameraCaptureSession> mBusySession;
@@ -203,6 +205,7 @@
***********************************/
// The current active session
ACameraCaptureSession* mCurrentSession = nullptr;
+ bool mFlushing = false;
int mNextSessionId = 0;
// TODO: might need another looper/handler to handle callbacks from service
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index f2e14b6..caae75f 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -303,7 +303,9 @@
const String8 value = drmInforequest->get(key);
if (key == String8("FileDescriptorKey")) {
int fd = -1;
- sscanf(value.string(), "FileDescriptor[%d]", &fd);
+ if (sscanf(value.string(), "FileDescriptor[%d]", &fd) != 1) {
+ sscanf(value.string(), "%d", &fd);
+ }
data.writeFileDescriptor(fd);
} else {
data.writeString8((value == String8("")) ? String8("NULL") : value);
diff --git a/drm/drmserver/main_drmserver.cpp b/drm/drmserver/main_drmserver.cpp
index 1ce42e8..8f697a4 100644
--- a/drm/drmserver/main_drmserver.cpp
+++ b/drm/drmserver/main_drmserver.cpp
@@ -28,6 +28,8 @@
int main()
{
+ signal(SIGPIPE, SIG_IGN);
+
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGV("ServiceManager: %p", sm.get());
diff --git a/include/camera/ndk/NdkCameraMetadataTags.h b/include/camera/ndk/NdkCameraMetadataTags.h
index a1d3bf7..afdd269 100644
--- a/include/camera/ndk/NdkCameraMetadataTags.h
+++ b/include/camera/ndk/NdkCameraMetadataTags.h
@@ -514,478 +514,476 @@
// ACAMERA_COLOR_CORRECTION_MODE
typedef enum acamera_metadata_enum_acamera_color_correction_mode {
- ACAMERA_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX,
- ACAMERA_COLOR_CORRECTION_MODE_FAST,
- ACAMERA_COLOR_CORRECTION_MODE_HIGH_QUALITY,
+ ACAMERA_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0,
+ ACAMERA_COLOR_CORRECTION_MODE_FAST = 1,
+ ACAMERA_COLOR_CORRECTION_MODE_HIGH_QUALITY = 2,
} acamera_metadata_enum_android_color_correction_mode_t;
// ACAMERA_COLOR_CORRECTION_ABERRATION_MODE
typedef enum acamera_metadata_enum_acamera_color_correction_aberration_mode {
- ACAMERA_COLOR_CORRECTION_ABERRATION_MODE_OFF,
- ACAMERA_COLOR_CORRECTION_ABERRATION_MODE_FAST,
- ACAMERA_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY,
+ ACAMERA_COLOR_CORRECTION_ABERRATION_MODE_OFF = 0,
+ ACAMERA_COLOR_CORRECTION_ABERRATION_MODE_FAST = 1,
+ ACAMERA_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY = 2,
} acamera_metadata_enum_android_color_correction_aberration_mode_t;
// ACAMERA_CONTROL_AE_ANTIBANDING_MODE
typedef enum acamera_metadata_enum_acamera_control_ae_antibanding_mode {
- ACAMERA_CONTROL_AE_ANTIBANDING_MODE_OFF,
- ACAMERA_CONTROL_AE_ANTIBANDING_MODE_50HZ,
- ACAMERA_CONTROL_AE_ANTIBANDING_MODE_60HZ,
- ACAMERA_CONTROL_AE_ANTIBANDING_MODE_AUTO,
+ ACAMERA_CONTROL_AE_ANTIBANDING_MODE_OFF = 0,
+ ACAMERA_CONTROL_AE_ANTIBANDING_MODE_50HZ = 1,
+ ACAMERA_CONTROL_AE_ANTIBANDING_MODE_60HZ = 2,
+ ACAMERA_CONTROL_AE_ANTIBANDING_MODE_AUTO = 3,
} acamera_metadata_enum_android_control_ae_antibanding_mode_t;
// ACAMERA_CONTROL_AE_LOCK
typedef enum acamera_metadata_enum_acamera_control_ae_lock {
- ACAMERA_CONTROL_AE_LOCK_OFF,
- ACAMERA_CONTROL_AE_LOCK_ON,
+ ACAMERA_CONTROL_AE_LOCK_OFF = 0,
+ ACAMERA_CONTROL_AE_LOCK_ON = 1,
} acamera_metadata_enum_android_control_ae_lock_t;
// ACAMERA_CONTROL_AE_MODE
typedef enum acamera_metadata_enum_acamera_control_ae_mode {
- ACAMERA_CONTROL_AE_MODE_OFF,
- ACAMERA_CONTROL_AE_MODE_ON,
- ACAMERA_CONTROL_AE_MODE_ON_AUTO_FLASH,
- ACAMERA_CONTROL_AE_MODE_ON_ALWAYS_FLASH,
- ACAMERA_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
+ ACAMERA_CONTROL_AE_MODE_OFF = 0,
+ ACAMERA_CONTROL_AE_MODE_ON = 1,
+ ACAMERA_CONTROL_AE_MODE_ON_AUTO_FLASH = 2,
+ ACAMERA_CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3,
+ ACAMERA_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4,
} acamera_metadata_enum_android_control_ae_mode_t;
// ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER
typedef enum acamera_metadata_enum_acamera_control_ae_precapture_trigger {
- ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE,
- ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_START,
- ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL,
+ ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE = 0,
+ ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_START = 1,
+ ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL = 2,
} acamera_metadata_enum_android_control_ae_precapture_trigger_t;
// ACAMERA_CONTROL_AF_MODE
typedef enum acamera_metadata_enum_acamera_control_af_mode {
- ACAMERA_CONTROL_AF_MODE_OFF,
- ACAMERA_CONTROL_AF_MODE_AUTO,
- ACAMERA_CONTROL_AF_MODE_MACRO,
- ACAMERA_CONTROL_AF_MODE_CONTINUOUS_VIDEO,
- ACAMERA_CONTROL_AF_MODE_CONTINUOUS_PICTURE,
- ACAMERA_CONTROL_AF_MODE_EDOF,
+ ACAMERA_CONTROL_AF_MODE_OFF = 0,
+ ACAMERA_CONTROL_AF_MODE_AUTO = 1,
+ ACAMERA_CONTROL_AF_MODE_MACRO = 2,
+ ACAMERA_CONTROL_AF_MODE_CONTINUOUS_VIDEO = 3,
+ ACAMERA_CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4,
+ ACAMERA_CONTROL_AF_MODE_EDOF = 5,
} acamera_metadata_enum_android_control_af_mode_t;
// ACAMERA_CONTROL_AF_TRIGGER
typedef enum acamera_metadata_enum_acamera_control_af_trigger {
- ACAMERA_CONTROL_AF_TRIGGER_IDLE,
- ACAMERA_CONTROL_AF_TRIGGER_START,
- ACAMERA_CONTROL_AF_TRIGGER_CANCEL,
+ ACAMERA_CONTROL_AF_TRIGGER_IDLE = 0,
+ ACAMERA_CONTROL_AF_TRIGGER_START = 1,
+ ACAMERA_CONTROL_AF_TRIGGER_CANCEL = 2,
} acamera_metadata_enum_android_control_af_trigger_t;
// ACAMERA_CONTROL_AWB_LOCK
typedef enum acamera_metadata_enum_acamera_control_awb_lock {
- ACAMERA_CONTROL_AWB_LOCK_OFF,
- ACAMERA_CONTROL_AWB_LOCK_ON,
+ ACAMERA_CONTROL_AWB_LOCK_OFF = 0,
+ ACAMERA_CONTROL_AWB_LOCK_ON = 1,
} acamera_metadata_enum_android_control_awb_lock_t;
// ACAMERA_CONTROL_AWB_MODE
typedef enum acamera_metadata_enum_acamera_control_awb_mode {
- ACAMERA_CONTROL_AWB_MODE_OFF,
- ACAMERA_CONTROL_AWB_MODE_AUTO,
- ACAMERA_CONTROL_AWB_MODE_INCANDESCENT,
- ACAMERA_CONTROL_AWB_MODE_FLUORESCENT,
- ACAMERA_CONTROL_AWB_MODE_WARM_FLUORESCENT,
- ACAMERA_CONTROL_AWB_MODE_DAYLIGHT,
- ACAMERA_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT,
- ACAMERA_CONTROL_AWB_MODE_TWILIGHT,
- ACAMERA_CONTROL_AWB_MODE_SHADE,
+ ACAMERA_CONTROL_AWB_MODE_OFF = 0,
+ ACAMERA_CONTROL_AWB_MODE_AUTO = 1,
+ ACAMERA_CONTROL_AWB_MODE_INCANDESCENT = 2,
+ ACAMERA_CONTROL_AWB_MODE_FLUORESCENT = 3,
+ ACAMERA_CONTROL_AWB_MODE_WARM_FLUORESCENT = 4,
+ ACAMERA_CONTROL_AWB_MODE_DAYLIGHT = 5,
+ ACAMERA_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6,
+ ACAMERA_CONTROL_AWB_MODE_TWILIGHT = 7,
+ ACAMERA_CONTROL_AWB_MODE_SHADE = 8,
} acamera_metadata_enum_android_control_awb_mode_t;
// ACAMERA_CONTROL_CAPTURE_INTENT
typedef enum acamera_metadata_enum_acamera_control_capture_intent {
- ACAMERA_CONTROL_CAPTURE_INTENT_CUSTOM,
- ACAMERA_CONTROL_CAPTURE_INTENT_PREVIEW,
- ACAMERA_CONTROL_CAPTURE_INTENT_STILL_CAPTURE,
- ACAMERA_CONTROL_CAPTURE_INTENT_VIDEO_RECORD,
- ACAMERA_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT,
- ACAMERA_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG,
- ACAMERA_CONTROL_CAPTURE_INTENT_MANUAL,
+ ACAMERA_CONTROL_CAPTURE_INTENT_CUSTOM = 0,
+ ACAMERA_CONTROL_CAPTURE_INTENT_PREVIEW = 1,
+ ACAMERA_CONTROL_CAPTURE_INTENT_STILL_CAPTURE = 2,
+ ACAMERA_CONTROL_CAPTURE_INTENT_VIDEO_RECORD = 3,
+ ACAMERA_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4,
+ ACAMERA_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5,
+ ACAMERA_CONTROL_CAPTURE_INTENT_MANUAL = 6,
} acamera_metadata_enum_android_control_capture_intent_t;
// ACAMERA_CONTROL_EFFECT_MODE
typedef enum acamera_metadata_enum_acamera_control_effect_mode {
- ACAMERA_CONTROL_EFFECT_MODE_OFF,
- ACAMERA_CONTROL_EFFECT_MODE_MONO,
- ACAMERA_CONTROL_EFFECT_MODE_NEGATIVE,
- ACAMERA_CONTROL_EFFECT_MODE_SOLARIZE,
- ACAMERA_CONTROL_EFFECT_MODE_SEPIA,
- ACAMERA_CONTROL_EFFECT_MODE_POSTERIZE,
- ACAMERA_CONTROL_EFFECT_MODE_WHITEBOARD,
- ACAMERA_CONTROL_EFFECT_MODE_BLACKBOARD,
- ACAMERA_CONTROL_EFFECT_MODE_AQUA,
+ ACAMERA_CONTROL_EFFECT_MODE_OFF = 0,
+ ACAMERA_CONTROL_EFFECT_MODE_MONO = 1,
+ ACAMERA_CONTROL_EFFECT_MODE_NEGATIVE = 2,
+ ACAMERA_CONTROL_EFFECT_MODE_SOLARIZE = 3,
+ ACAMERA_CONTROL_EFFECT_MODE_SEPIA = 4,
+ ACAMERA_CONTROL_EFFECT_MODE_POSTERIZE = 5,
+ ACAMERA_CONTROL_EFFECT_MODE_WHITEBOARD = 6,
+ ACAMERA_CONTROL_EFFECT_MODE_BLACKBOARD = 7,
+ ACAMERA_CONTROL_EFFECT_MODE_AQUA = 8,
} acamera_metadata_enum_android_control_effect_mode_t;
// ACAMERA_CONTROL_MODE
typedef enum acamera_metadata_enum_acamera_control_mode {
- ACAMERA_CONTROL_MODE_OFF,
- ACAMERA_CONTROL_MODE_AUTO,
- ACAMERA_CONTROL_MODE_USE_SCENE_MODE,
- ACAMERA_CONTROL_MODE_OFF_KEEP_STATE,
+ ACAMERA_CONTROL_MODE_OFF = 0,
+ ACAMERA_CONTROL_MODE_AUTO = 1,
+ ACAMERA_CONTROL_MODE_USE_SCENE_MODE = 2,
+ ACAMERA_CONTROL_MODE_OFF_KEEP_STATE = 3,
} acamera_metadata_enum_android_control_mode_t;
// ACAMERA_CONTROL_SCENE_MODE
typedef enum acamera_metadata_enum_acamera_control_scene_mode {
- ACAMERA_CONTROL_SCENE_MODE_DISABLED = 0,
- ACAMERA_CONTROL_SCENE_MODE_FACE_PRIORITY,
- ACAMERA_CONTROL_SCENE_MODE_ACTION,
- ACAMERA_CONTROL_SCENE_MODE_PORTRAIT,
- ACAMERA_CONTROL_SCENE_MODE_LANDSCAPE,
- ACAMERA_CONTROL_SCENE_MODE_NIGHT,
- ACAMERA_CONTROL_SCENE_MODE_NIGHT_PORTRAIT,
- ACAMERA_CONTROL_SCENE_MODE_THEATRE,
- ACAMERA_CONTROL_SCENE_MODE_BEACH,
- ACAMERA_CONTROL_SCENE_MODE_SNOW,
- ACAMERA_CONTROL_SCENE_MODE_SUNSET,
- ACAMERA_CONTROL_SCENE_MODE_STEADYPHOTO,
- ACAMERA_CONTROL_SCENE_MODE_FIREWORKS,
- ACAMERA_CONTROL_SCENE_MODE_SPORTS,
- ACAMERA_CONTROL_SCENE_MODE_PARTY,
- ACAMERA_CONTROL_SCENE_MODE_CANDLELIGHT,
- ACAMERA_CONTROL_SCENE_MODE_BARCODE,
- ACAMERA_CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO,
- ACAMERA_CONTROL_SCENE_MODE_HDR,
- ACAMERA_CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT,
- ACAMERA_CONTROL_SCENE_MODE_DEVICE_CUSTOM_START = 100,
- ACAMERA_CONTROL_SCENE_MODE_DEVICE_CUSTOM_END = 127,
+ ACAMERA_CONTROL_SCENE_MODE_DISABLED = 0,
+ ACAMERA_CONTROL_SCENE_MODE_FACE_PRIORITY = 1,
+ ACAMERA_CONTROL_SCENE_MODE_ACTION = 2,
+ ACAMERA_CONTROL_SCENE_MODE_PORTRAIT = 3,
+ ACAMERA_CONTROL_SCENE_MODE_LANDSCAPE = 4,
+ ACAMERA_CONTROL_SCENE_MODE_NIGHT = 5,
+ ACAMERA_CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6,
+ ACAMERA_CONTROL_SCENE_MODE_THEATRE = 7,
+ ACAMERA_CONTROL_SCENE_MODE_BEACH = 8,
+ ACAMERA_CONTROL_SCENE_MODE_SNOW = 9,
+ ACAMERA_CONTROL_SCENE_MODE_SUNSET = 10,
+ ACAMERA_CONTROL_SCENE_MODE_STEADYPHOTO = 11,
+ ACAMERA_CONTROL_SCENE_MODE_FIREWORKS = 12,
+ ACAMERA_CONTROL_SCENE_MODE_SPORTS = 13,
+ ACAMERA_CONTROL_SCENE_MODE_PARTY = 14,
+ ACAMERA_CONTROL_SCENE_MODE_CANDLELIGHT = 15,
+ ACAMERA_CONTROL_SCENE_MODE_BARCODE = 16,
+ ACAMERA_CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17,
+ ACAMERA_CONTROL_SCENE_MODE_HDR = 18,
} acamera_metadata_enum_android_control_scene_mode_t;
// ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE
typedef enum acamera_metadata_enum_acamera_control_video_stabilization_mode {
- ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
- ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE_ON,
+ ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE_OFF = 0,
+ ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE_ON = 1,
} acamera_metadata_enum_android_control_video_stabilization_mode_t;
// ACAMERA_CONTROL_AE_STATE
typedef enum acamera_metadata_enum_acamera_control_ae_state {
- ACAMERA_CONTROL_AE_STATE_INACTIVE,
- ACAMERA_CONTROL_AE_STATE_SEARCHING,
- ACAMERA_CONTROL_AE_STATE_CONVERGED,
- ACAMERA_CONTROL_AE_STATE_LOCKED,
- ACAMERA_CONTROL_AE_STATE_FLASH_REQUIRED,
- ACAMERA_CONTROL_AE_STATE_PRECAPTURE,
+ ACAMERA_CONTROL_AE_STATE_INACTIVE = 0,
+ ACAMERA_CONTROL_AE_STATE_SEARCHING = 1,
+ ACAMERA_CONTROL_AE_STATE_CONVERGED = 2,
+ ACAMERA_CONTROL_AE_STATE_LOCKED = 3,
+ ACAMERA_CONTROL_AE_STATE_FLASH_REQUIRED = 4,
+ ACAMERA_CONTROL_AE_STATE_PRECAPTURE = 5,
} acamera_metadata_enum_android_control_ae_state_t;
// ACAMERA_CONTROL_AF_STATE
typedef enum acamera_metadata_enum_acamera_control_af_state {
- ACAMERA_CONTROL_AF_STATE_INACTIVE,
- ACAMERA_CONTROL_AF_STATE_PASSIVE_SCAN,
- ACAMERA_CONTROL_AF_STATE_PASSIVE_FOCUSED,
- ACAMERA_CONTROL_AF_STATE_ACTIVE_SCAN,
- ACAMERA_CONTROL_AF_STATE_FOCUSED_LOCKED,
- ACAMERA_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED,
- ACAMERA_CONTROL_AF_STATE_PASSIVE_UNFOCUSED,
+ ACAMERA_CONTROL_AF_STATE_INACTIVE = 0,
+ ACAMERA_CONTROL_AF_STATE_PASSIVE_SCAN = 1,
+ ACAMERA_CONTROL_AF_STATE_PASSIVE_FOCUSED = 2,
+ ACAMERA_CONTROL_AF_STATE_ACTIVE_SCAN = 3,
+ ACAMERA_CONTROL_AF_STATE_FOCUSED_LOCKED = 4,
+ ACAMERA_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5,
+ ACAMERA_CONTROL_AF_STATE_PASSIVE_UNFOCUSED = 6,
} acamera_metadata_enum_android_control_af_state_t;
// ACAMERA_CONTROL_AWB_STATE
typedef enum acamera_metadata_enum_acamera_control_awb_state {
- ACAMERA_CONTROL_AWB_STATE_INACTIVE,
- ACAMERA_CONTROL_AWB_STATE_SEARCHING,
- ACAMERA_CONTROL_AWB_STATE_CONVERGED,
- ACAMERA_CONTROL_AWB_STATE_LOCKED,
+ ACAMERA_CONTROL_AWB_STATE_INACTIVE = 0,
+ ACAMERA_CONTROL_AWB_STATE_SEARCHING = 1,
+ ACAMERA_CONTROL_AWB_STATE_CONVERGED = 2,
+ ACAMERA_CONTROL_AWB_STATE_LOCKED = 3,
} acamera_metadata_enum_android_control_awb_state_t;
// ACAMERA_CONTROL_AE_LOCK_AVAILABLE
typedef enum acamera_metadata_enum_acamera_control_ae_lock_available {
- ACAMERA_CONTROL_AE_LOCK_AVAILABLE_FALSE,
- ACAMERA_CONTROL_AE_LOCK_AVAILABLE_TRUE,
+ ACAMERA_CONTROL_AE_LOCK_AVAILABLE_FALSE = 0,
+ ACAMERA_CONTROL_AE_LOCK_AVAILABLE_TRUE = 1,
} acamera_metadata_enum_android_control_ae_lock_available_t;
// ACAMERA_CONTROL_AWB_LOCK_AVAILABLE
typedef enum acamera_metadata_enum_acamera_control_awb_lock_available {
- ACAMERA_CONTROL_AWB_LOCK_AVAILABLE_FALSE,
- ACAMERA_CONTROL_AWB_LOCK_AVAILABLE_TRUE,
+ ACAMERA_CONTROL_AWB_LOCK_AVAILABLE_FALSE = 0,
+ ACAMERA_CONTROL_AWB_LOCK_AVAILABLE_TRUE = 1,
} acamera_metadata_enum_android_control_awb_lock_available_t;
// ACAMERA_EDGE_MODE
typedef enum acamera_metadata_enum_acamera_edge_mode {
- ACAMERA_EDGE_MODE_OFF,
- ACAMERA_EDGE_MODE_FAST,
- ACAMERA_EDGE_MODE_HIGH_QUALITY,
- ACAMERA_EDGE_MODE_ZERO_SHUTTER_LAG,
+ ACAMERA_EDGE_MODE_OFF = 0,
+ ACAMERA_EDGE_MODE_FAST = 1,
+ ACAMERA_EDGE_MODE_HIGH_QUALITY = 2,
+ ACAMERA_EDGE_MODE_ZERO_SHUTTER_LAG = 3,
} acamera_metadata_enum_android_edge_mode_t;
// ACAMERA_FLASH_MODE
typedef enum acamera_metadata_enum_acamera_flash_mode {
- ACAMERA_FLASH_MODE_OFF,
- ACAMERA_FLASH_MODE_SINGLE,
- ACAMERA_FLASH_MODE_TORCH,
+ ACAMERA_FLASH_MODE_OFF = 0,
+ ACAMERA_FLASH_MODE_SINGLE = 1,
+ ACAMERA_FLASH_MODE_TORCH = 2,
} acamera_metadata_enum_android_flash_mode_t;
// ACAMERA_FLASH_STATE
typedef enum acamera_metadata_enum_acamera_flash_state {
- ACAMERA_FLASH_STATE_UNAVAILABLE,
- ACAMERA_FLASH_STATE_CHARGING,
- ACAMERA_FLASH_STATE_READY,
- ACAMERA_FLASH_STATE_FIRED,
- ACAMERA_FLASH_STATE_PARTIAL,
+ ACAMERA_FLASH_STATE_UNAVAILABLE = 0,
+ ACAMERA_FLASH_STATE_CHARGING = 1,
+ ACAMERA_FLASH_STATE_READY = 2,
+ ACAMERA_FLASH_STATE_FIRED = 3,
+ ACAMERA_FLASH_STATE_PARTIAL = 4,
} acamera_metadata_enum_android_flash_state_t;
// ACAMERA_FLASH_INFO_AVAILABLE
typedef enum acamera_metadata_enum_acamera_flash_info_available {
- ACAMERA_FLASH_INFO_AVAILABLE_FALSE,
- ACAMERA_FLASH_INFO_AVAILABLE_TRUE,
+ ACAMERA_FLASH_INFO_AVAILABLE_FALSE = 0,
+ ACAMERA_FLASH_INFO_AVAILABLE_TRUE = 1,
} acamera_metadata_enum_android_flash_info_available_t;
// ACAMERA_HOT_PIXEL_MODE
typedef enum acamera_metadata_enum_acamera_hot_pixel_mode {
- ACAMERA_HOT_PIXEL_MODE_OFF,
- ACAMERA_HOT_PIXEL_MODE_FAST,
- ACAMERA_HOT_PIXEL_MODE_HIGH_QUALITY,
+ ACAMERA_HOT_PIXEL_MODE_OFF = 0,
+ ACAMERA_HOT_PIXEL_MODE_FAST = 1,
+ ACAMERA_HOT_PIXEL_MODE_HIGH_QUALITY = 2,
} acamera_metadata_enum_android_hot_pixel_mode_t;
// ACAMERA_LENS_OPTICAL_STABILIZATION_MODE
typedef enum acamera_metadata_enum_acamera_lens_optical_stabilization_mode {
- ACAMERA_LENS_OPTICAL_STABILIZATION_MODE_OFF,
- ACAMERA_LENS_OPTICAL_STABILIZATION_MODE_ON,
+ ACAMERA_LENS_OPTICAL_STABILIZATION_MODE_OFF = 0,
+ ACAMERA_LENS_OPTICAL_STABILIZATION_MODE_ON = 1,
} acamera_metadata_enum_android_lens_optical_stabilization_mode_t;
// ACAMERA_LENS_FACING
typedef enum acamera_metadata_enum_acamera_lens_facing {
- ACAMERA_LENS_FACING_FRONT,
- ACAMERA_LENS_FACING_BACK,
- ACAMERA_LENS_FACING_EXTERNAL,
+ ACAMERA_LENS_FACING_FRONT = 0,
+ ACAMERA_LENS_FACING_BACK = 1,
+ ACAMERA_LENS_FACING_EXTERNAL = 2,
} acamera_metadata_enum_android_lens_facing_t;
// ACAMERA_LENS_STATE
typedef enum acamera_metadata_enum_acamera_lens_state {
- ACAMERA_LENS_STATE_STATIONARY,
- ACAMERA_LENS_STATE_MOVING,
+ ACAMERA_LENS_STATE_STATIONARY = 0,
+ ACAMERA_LENS_STATE_MOVING = 1,
} acamera_metadata_enum_android_lens_state_t;
// ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION
typedef enum acamera_metadata_enum_acamera_lens_info_focus_distance_calibration {
- ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED,
- ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE,
- ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED,
+ ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED = 0,
+ ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE = 1,
+ ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED = 2,
} acamera_metadata_enum_android_lens_info_focus_distance_calibration_t;
// ACAMERA_NOISE_REDUCTION_MODE
typedef enum acamera_metadata_enum_acamera_noise_reduction_mode {
- ACAMERA_NOISE_REDUCTION_MODE_OFF,
- ACAMERA_NOISE_REDUCTION_MODE_FAST,
- ACAMERA_NOISE_REDUCTION_MODE_HIGH_QUALITY,
- ACAMERA_NOISE_REDUCTION_MODE_MINIMAL,
- ACAMERA_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG,
+ ACAMERA_NOISE_REDUCTION_MODE_OFF = 0,
+ ACAMERA_NOISE_REDUCTION_MODE_FAST = 1,
+ ACAMERA_NOISE_REDUCTION_MODE_HIGH_QUALITY = 2,
+ ACAMERA_NOISE_REDUCTION_MODE_MINIMAL = 3,
+ ACAMERA_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG = 4,
} acamera_metadata_enum_android_noise_reduction_mode_t;
// ACAMERA_QUIRKS_PARTIAL_RESULT
typedef enum acamera_metadata_enum_acamera_quirks_partial_result {
- ACAMERA_QUIRKS_PARTIAL_RESULT_FINAL,
- ACAMERA_QUIRKS_PARTIAL_RESULT_PARTIAL,
+ ACAMERA_QUIRKS_PARTIAL_RESULT_FINAL = 0,
+ ACAMERA_QUIRKS_PARTIAL_RESULT_PARTIAL = 1,
} acamera_metadata_enum_android_quirks_partial_result_t;
// ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
typedef enum acamera_metadata_enum_acamera_request_available_capabilities {
- ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
- ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR,
- ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING,
- ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_RAW,
- ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING,
- ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS,
- ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE,
- ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING,
- ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT,
- ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_RAW = 3,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO
+ = 9,
} acamera_metadata_enum_android_request_available_capabilities_t;
// ACAMERA_SCALER_AVAILABLE_FORMATS
typedef enum acamera_metadata_enum_acamera_scaler_available_formats {
- ACAMERA_SCALER_AVAILABLE_FORMATS_RAW16 = 0x20,
- ACAMERA_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE = 0x24,
- ACAMERA_SCALER_AVAILABLE_FORMATS_YV12 = 0x32315659,
- ACAMERA_SCALER_AVAILABLE_FORMATS_YCrCb_420_SP = 0x11,
- ACAMERA_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED = 0x22,
- ACAMERA_SCALER_AVAILABLE_FORMATS_YCbCr_420_888 = 0x23,
- ACAMERA_SCALER_AVAILABLE_FORMATS_BLOB = 0x21,
+ ACAMERA_SCALER_AVAILABLE_FORMATS_RAW16 = 0x20,
+ ACAMERA_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE = 0x24,
+ ACAMERA_SCALER_AVAILABLE_FORMATS_YV12 = 0x32315659,
+ ACAMERA_SCALER_AVAILABLE_FORMATS_YCrCb_420_SP = 0x11,
+ ACAMERA_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED = 0x22,
+ ACAMERA_SCALER_AVAILABLE_FORMATS_YCbCr_420_888 = 0x23,
+ ACAMERA_SCALER_AVAILABLE_FORMATS_BLOB = 0x21,
} acamera_metadata_enum_android_scaler_available_formats_t;
// ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
typedef enum acamera_metadata_enum_acamera_scaler_available_stream_configurations {
- ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
- ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT,
+ ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT = 0,
+ ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT = 1,
} acamera_metadata_enum_android_scaler_available_stream_configurations_t;
// ACAMERA_SCALER_CROPPING_TYPE
typedef enum acamera_metadata_enum_acamera_scaler_cropping_type {
- ACAMERA_SCALER_CROPPING_TYPE_CENTER_ONLY,
- ACAMERA_SCALER_CROPPING_TYPE_FREEFORM,
+ ACAMERA_SCALER_CROPPING_TYPE_CENTER_ONLY = 0,
+ ACAMERA_SCALER_CROPPING_TYPE_FREEFORM = 1,
} acamera_metadata_enum_android_scaler_cropping_type_t;
// ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
typedef enum acamera_metadata_enum_acamera_sensor_reference_illuminant1 {
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT = 1,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT = 2,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN = 3,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_FLASH = 4,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_FINE_WEATHER = 9,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER = 10,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_SHADE = 11,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT = 12,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT = 13,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT = 14,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT = 15,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A = 17,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B = 18,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C = 19,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_D55 = 20,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_D65 = 21,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_D75 = 22,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_D50 = 23,
- ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN = 24,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT = 1,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT = 2,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN = 3,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_FLASH = 4,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_FINE_WEATHER = 9,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER = 10,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_SHADE = 11,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT = 12,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT = 13,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT = 14,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT = 15,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A = 17,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B = 18,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C = 19,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_D55 = 20,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_D65 = 21,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_D75 = 22,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_D50 = 23,
+ ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN = 24,
} acamera_metadata_enum_android_sensor_reference_illuminant1_t;
// ACAMERA_SENSOR_TEST_PATTERN_MODE
typedef enum acamera_metadata_enum_acamera_sensor_test_pattern_mode {
- ACAMERA_SENSOR_TEST_PATTERN_MODE_OFF,
- ACAMERA_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR,
- ACAMERA_SENSOR_TEST_PATTERN_MODE_COLOR_BARS,
- ACAMERA_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY,
- ACAMERA_SENSOR_TEST_PATTERN_MODE_PN9,
- ACAMERA_SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256,
+ ACAMERA_SENSOR_TEST_PATTERN_MODE_OFF = 0,
+ ACAMERA_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR = 1,
+ ACAMERA_SENSOR_TEST_PATTERN_MODE_COLOR_BARS = 2,
+ ACAMERA_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY = 3,
+ ACAMERA_SENSOR_TEST_PATTERN_MODE_PN9 = 4,
+ ACAMERA_SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256,
} acamera_metadata_enum_android_sensor_test_pattern_mode_t;
// ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
typedef enum acamera_metadata_enum_acamera_sensor_info_color_filter_arrangement {
- ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB,
- ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG,
- ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG,
- ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR,
- ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB,
+ ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB = 0,
+ ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG = 1,
+ ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG = 2,
+ ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR = 3,
+ ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4,
} acamera_metadata_enum_android_sensor_info_color_filter_arrangement_t;
// ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE
typedef enum acamera_metadata_enum_acamera_sensor_info_timestamp_source {
- ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN,
- ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME,
+ ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN = 0,
+ ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME = 1,
} acamera_metadata_enum_android_sensor_info_timestamp_source_t;
// ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED
typedef enum acamera_metadata_enum_acamera_sensor_info_lens_shading_applied {
- ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED_FALSE,
- ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED_TRUE,
+ ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED_FALSE = 0,
+ ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED_TRUE = 1,
} acamera_metadata_enum_android_sensor_info_lens_shading_applied_t;
// ACAMERA_SHADING_MODE
typedef enum acamera_metadata_enum_acamera_shading_mode {
- ACAMERA_SHADING_MODE_OFF,
- ACAMERA_SHADING_MODE_FAST,
- ACAMERA_SHADING_MODE_HIGH_QUALITY,
+ ACAMERA_SHADING_MODE_OFF = 0,
+ ACAMERA_SHADING_MODE_FAST = 1,
+ ACAMERA_SHADING_MODE_HIGH_QUALITY = 2,
} acamera_metadata_enum_android_shading_mode_t;
// ACAMERA_STATISTICS_FACE_DETECT_MODE
typedef enum acamera_metadata_enum_acamera_statistics_face_detect_mode {
- ACAMERA_STATISTICS_FACE_DETECT_MODE_OFF,
- ACAMERA_STATISTICS_FACE_DETECT_MODE_SIMPLE,
- ACAMERA_STATISTICS_FACE_DETECT_MODE_FULL,
+ ACAMERA_STATISTICS_FACE_DETECT_MODE_OFF = 0,
+ ACAMERA_STATISTICS_FACE_DETECT_MODE_SIMPLE = 1,
+ ACAMERA_STATISTICS_FACE_DETECT_MODE_FULL = 2,
} acamera_metadata_enum_android_statistics_face_detect_mode_t;
// ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE
typedef enum acamera_metadata_enum_acamera_statistics_hot_pixel_map_mode {
- ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE_OFF,
- ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE_ON,
+ ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE_OFF = 0,
+ ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE_ON = 1,
} acamera_metadata_enum_android_statistics_hot_pixel_map_mode_t;
// ACAMERA_STATISTICS_SCENE_FLICKER
typedef enum acamera_metadata_enum_acamera_statistics_scene_flicker {
- ACAMERA_STATISTICS_SCENE_FLICKER_NONE,
- ACAMERA_STATISTICS_SCENE_FLICKER_50HZ,
- ACAMERA_STATISTICS_SCENE_FLICKER_60HZ,
+ ACAMERA_STATISTICS_SCENE_FLICKER_NONE = 0,
+ ACAMERA_STATISTICS_SCENE_FLICKER_50HZ = 1,
+ ACAMERA_STATISTICS_SCENE_FLICKER_60HZ = 2,
} acamera_metadata_enum_android_statistics_scene_flicker_t;
// ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE
typedef enum acamera_metadata_enum_acamera_statistics_lens_shading_map_mode {
- ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE_OFF,
- ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE_ON,
+ ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0,
+ ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE_ON = 1,
} acamera_metadata_enum_android_statistics_lens_shading_map_mode_t;
// ACAMERA_TONEMAP_MODE
typedef enum acamera_metadata_enum_acamera_tonemap_mode {
- ACAMERA_TONEMAP_MODE_CONTRAST_CURVE,
- ACAMERA_TONEMAP_MODE_FAST,
- ACAMERA_TONEMAP_MODE_HIGH_QUALITY,
- ACAMERA_TONEMAP_MODE_GAMMA_VALUE,
- ACAMERA_TONEMAP_MODE_PRESET_CURVE,
+ ACAMERA_TONEMAP_MODE_CONTRAST_CURVE = 0,
+ ACAMERA_TONEMAP_MODE_FAST = 1,
+ ACAMERA_TONEMAP_MODE_HIGH_QUALITY = 2,
+ ACAMERA_TONEMAP_MODE_GAMMA_VALUE = 3,
+ ACAMERA_TONEMAP_MODE_PRESET_CURVE = 4,
} acamera_metadata_enum_android_tonemap_mode_t;
// ACAMERA_TONEMAP_PRESET_CURVE
typedef enum acamera_metadata_enum_acamera_tonemap_preset_curve {
- ACAMERA_TONEMAP_PRESET_CURVE_SRGB,
- ACAMERA_TONEMAP_PRESET_CURVE_REC709,
+ ACAMERA_TONEMAP_PRESET_CURVE_SRGB = 0,
+ ACAMERA_TONEMAP_PRESET_CURVE_REC709 = 1,
} acamera_metadata_enum_android_tonemap_preset_curve_t;
// ACAMERA_LED_TRANSMIT
typedef enum acamera_metadata_enum_acamera_led_transmit {
- ACAMERA_LED_TRANSMIT_OFF,
- ACAMERA_LED_TRANSMIT_ON,
+ ACAMERA_LED_TRANSMIT_OFF = 0,
+ ACAMERA_LED_TRANSMIT_ON = 1,
} acamera_metadata_enum_android_led_transmit_t;
// ACAMERA_LED_AVAILABLE_LEDS
typedef enum acamera_metadata_enum_acamera_led_available_leds {
- ACAMERA_LED_AVAILABLE_LEDS_TRANSMIT,
+ ACAMERA_LED_AVAILABLE_LEDS_TRANSMIT = 0,
} acamera_metadata_enum_android_led_available_leds_t;
// ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL
typedef enum acamera_metadata_enum_acamera_info_supported_hardware_level {
- ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED,
- ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_FULL,
- ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY,
- ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_3,
+ ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0,
+ ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1,
+ ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2,
+ ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3,
} acamera_metadata_enum_android_info_supported_hardware_level_t;
// ACAMERA_BLACK_LEVEL_LOCK
typedef enum acamera_metadata_enum_acamera_black_level_lock {
- ACAMERA_BLACK_LEVEL_LOCK_OFF,
- ACAMERA_BLACK_LEVEL_LOCK_ON,
+ ACAMERA_BLACK_LEVEL_LOCK_OFF = 0,
+ ACAMERA_BLACK_LEVEL_LOCK_ON = 1,
} acamera_metadata_enum_android_black_level_lock_t;
// ACAMERA_SYNC_FRAME_NUMBER
typedef enum acamera_metadata_enum_acamera_sync_frame_number {
- ACAMERA_SYNC_FRAME_NUMBER_CONVERGING = -1,
- ACAMERA_SYNC_FRAME_NUMBER_UNKNOWN = -2,
+ ACAMERA_SYNC_FRAME_NUMBER_CONVERGING = -1,
+ ACAMERA_SYNC_FRAME_NUMBER_UNKNOWN = -2,
} acamera_metadata_enum_android_sync_frame_number_t;
// ACAMERA_SYNC_MAX_LATENCY
typedef enum acamera_metadata_enum_acamera_sync_max_latency {
- ACAMERA_SYNC_MAX_LATENCY_PER_FRAME_CONTROL = 0,
- ACAMERA_SYNC_MAX_LATENCY_UNKNOWN = -1,
+ ACAMERA_SYNC_MAX_LATENCY_PER_FRAME_CONTROL = 0,
+ ACAMERA_SYNC_MAX_LATENCY_UNKNOWN = -1,
} acamera_metadata_enum_android_sync_max_latency_t;
// ACAMERA_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS
typedef enum acamera_metadata_enum_acamera_depth_available_depth_stream_configurations {
- ACAMERA_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
- ACAMERA_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_INPUT,
+ ACAMERA_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT = 0,
+ ACAMERA_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_INPUT = 1,
} acamera_metadata_enum_android_depth_available_depth_stream_configurations_t;
// ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE
typedef enum acamera_metadata_enum_acamera_depth_depth_is_exclusive {
- ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE,
- ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE_TRUE,
+ ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE = 0,
+ ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE_TRUE = 1,
} acamera_metadata_enum_android_depth_depth_is_exclusive_t;
diff --git a/include/media/AudioTimestamp.h b/include/media/AudioTimestamp.h
index 531b548..969003c 100644
--- a/include/media/AudioTimestamp.h
+++ b/include/media/AudioTimestamp.h
@@ -69,12 +69,23 @@
// or NTP adjustment.
int64_t mTimebaseOffset[TIMEBASE_MAX];
+ // Playback only:
+ // mFlushed is number of flushed frames before entering the server mix;
+ // hence not included in mPosition. This is used for adjusting server positions
+ // information for frames "dropped".
+ // FIXME: This variable should be eliminated, with the offset added on the server side
+ // before sending to client, but differences in legacy position offset handling
+ // and new extended timestamps require this to be maintained as a separate quantity.
+ int64_t mFlushed;
+
+ // Call to reset the timestamp to the original (invalid) state
void clear() {
memset(mPosition, 0, sizeof(mPosition)); // actually not necessary if time is -1
for (int i = 0; i < LOCATION_MAX; ++i) {
mTimeNs[i] = -1;
}
memset(mTimebaseOffset, 0, sizeof(mTimebaseOffset));
+ mFlushed = 0;
}
// Returns the best timestamp as judged from the closest-to-hw stage in the
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index bdd6372..eaaef4a 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -727,12 +727,54 @@
* because the audio device changed or AudioFlinger died.
* This typically occurs for direct or offload tracks
* or if mDoNotReconnect is true.
- * INVALID_OPERATION if called on a FastTrack, wrong state, or some other error.
+ * INVALID_OPERATION wrong state, or some other error.
*
* The timestamp parameter is undefined on return, if status is not NO_ERROR.
*/
status_t getTimestamp(AudioTimestamp& timestamp);
+ /* Return the extended timestamp, with additional timebase info and improved drain behavior.
+ *
+ * This is similar to the AudioTrack.java API:
+ * getTimestamp(@NonNull AudioTimestamp timestamp, @AudioTimestamp.Timebase int timebase)
+ *
+ * Some differences between this method and the getTimestamp(AudioTimestamp& timestamp) method
+ *
+ * 1. stop() by itself does not reset the frame position.
+ * A following start() resets the frame position to 0.
+ * 2. flush() by itself does not reset the frame position.
+ * The frame position advances by the number of frames flushed,
+ * when the first frame after flush reaches the audio sink.
+ * 3. BOOTTIME clock offsets are provided to help synchronize with
+ * non-audio streams, e.g. sensor data.
+ * 4. Position is returned with 64 bits of resolution.
+ *
+ * Parameters:
+ * timestamp: A pointer to the caller allocated ExtendedTimestamp.
+ *
+ * Returns NO_ERROR on success; timestamp is filled with valid data.
+ * BAD_VALUE if timestamp is NULL.
+ * WOULD_BLOCK if called immediately after start() when the number
+ * of frames consumed is less than the
+ * overall hardware latency to physical output. In WOULD_BLOCK cases,
+ * one might poll again, or use getPosition(), or use 0 position and
+ * current time for the timestamp.
+ * If WOULD_BLOCK is returned, the timestamp is still
+ * modified with the LOCATION_CLIENT portion filled.
+ * DEAD_OBJECT if AudioFlinger dies or the output device changes and
+ * the track cannot be automatically restored.
+ * The application needs to recreate the AudioTrack
+ * because the audio device changed or AudioFlinger died.
+ * This typically occurs for direct or offloaded tracks
+ * or if mDoNotReconnect is true.
+ * INVALID_OPERATION if called on a offloaded or direct track.
+ * Use getTimestamp(AudioTimestamp& timestamp) instead.
+ */
+ status_t getTimestamp(ExtendedTimestamp *timestamp);
+private:
+ status_t getTimestamp_l(ExtendedTimestamp *timestamp);
+public:
+
/* Add an AudioDeviceCallback. The caller will be notified when the audio device to which this
* AudioTrack is routed is updated.
* Replaces any previously installed callback.
@@ -755,6 +797,23 @@
status_t removeAudioDeviceCallback(
const sp<AudioSystem::AudioDeviceCallback>& callback);
+ /* Obtain the pending duration in milliseconds for playback of pure PCM
+ * (mixable without embedded timing) data remaining in AudioTrack.
+ *
+ * This is used to estimate the drain time for the client-server buffer
+ * so the choice of ExtendedTimestamp::LOCATION_SERVER is default.
+ * One may optionally request to find the duration to play through the HAL
+ * by specifying a location ExtendedTimestamp::LOCATION_KERNEL; however,
+ * INVALID_OPERATION may be returned if the kernel location is unavailable.
+ *
+ * Returns NO_ERROR if successful.
+ * INVALID_OPERATION if ExtendedTimestamp::LOCATION_KERNEL cannot be obtained
+ * or the AudioTrack does not contain pure PCM data.
+ * BAD_VALUE if msec is nullptr or location is invalid.
+ */
+ status_t pendingDuration(int32_t *msec,
+ ExtendedTimestamp::Location location = ExtendedTimestamp::LOCATION_SERVER);
+
protected:
/* copying audio tracks is not allowed */
AudioTrack(const AudioTrack& other);
@@ -956,6 +1015,13 @@
uint32_t mUnderrunCountOffset; // updated when restoring tracks
+ int64_t mFramesWritten; // total frames written. reset to zero after
+ // the start() following stop(). It is not
+ // changed after restoring the track or
+ // after flush.
+ int64_t mFramesWrittenServerOffset; // An offset to server frames due to
+ // restoring AudioTrack, or stop/start.
+
audio_output_flags_t mFlags; // same as mOrigFlags, except for bits that may
// be denied by client or server, such as
// AUDIO_OUTPUT_FLAG_FAST. mLock must be
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index dcde36f..c5e09c0 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -107,6 +107,8 @@
virtual String8 getMIMEType() const;
+ virtual void close() {};
+
protected:
virtual ~DataSource() {}
diff --git a/include/media/stagefright/foundation/AUtils.h b/include/media/stagefright/foundation/AUtils.h
index 47444c1..255a0f4 100644
--- a/include/media/stagefright/foundation/AUtils.h
+++ b/include/media/stagefright/foundation/AUtils.h
@@ -68,6 +68,7 @@
// needle is in range [hayStart, hayStart + haySize)
template<class T, class U>
+__attribute__((no_sanitize("integer")))
inline static bool isInRange(const T &hayStart, const U &haySize, const T &needle) {
ENSURE_UNSIGNED_TYPE<U>();
return (T)(hayStart + haySize) >= hayStart && needle >= hayStart && (U)(needle - hayStart) < haySize;
@@ -75,6 +76,7 @@
// [needleStart, needleStart + needleSize) is in range [hayStart, hayStart + haySize)
template<class T, class U>
+__attribute__((no_sanitize("integer")))
inline static bool isInRange(
const T &hayStart, const U &haySize, const T &needleStart, const U &needleSize) {
ENSURE_UNSIGNED_TYPE<U>();
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 92cf6bb..ffdb9b5 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -522,6 +522,9 @@
mTimestampMutator.push(timestamp);
}
+ // Total count of the number of flushed frames since creation (never reset).
+ virtual int64_t framesFlushed() const { return mFlushed; }
+
// Get dynamic buffer size from the shared control block.
uint32_t getBufferSizeInFrames() const {
return android_atomic_acquire_load((int32_t *)&mCblk->mBufferSizeInFrames);
@@ -531,7 +534,7 @@
size_t mAvailToClient; // estimated frames available to client prior to releaseBuffer()
int32_t mFlush; // our copy of cblk->u.mStreaming.mFlush, for streaming output only
int64_t mReleased; // our copy of cblk->mServer, at 64 bit resolution
-
+ int64_t mFlushed; // flushed frames to account for client-server discrepancy
ExtendedTimestampQueue::Mutator mTimestampMutator;
};
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index e70c611..e757c7c 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -500,6 +500,8 @@
mTimestampStartupGlitchReported = false;
mRetrogradeMotionReported = false;
mUnderrunCountOffset = 0;
+ mFramesWritten = 0;
+ mFramesWrittenServerOffset = 0;
return NO_ERROR;
}
@@ -537,6 +539,14 @@
// Note: the if is technically unnecessary because previousState == STATE_FLUSHED
// is only for streaming tracks, and mMarkerReached is already set to false.
if (previousState == STATE_STOPPED) {
+ // read last server side position change via timestamp
+ ExtendedTimestamp ets;
+ if (mProxy->getTimestamp(&ets) == OK &&
+ ets.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] > 0) {
+ mFramesWrittenServerOffset = -(ets.mPosition[ExtendedTimestamp::LOCATION_SERVER]
+ + ets.mFlushed);
+ }
+ mFramesWritten = 0;
mProxy->clearTimestamp(); // need new server push for valid timestamp
mMarkerReached = false;
}
@@ -1657,6 +1667,9 @@
releaseBuffer(&audioBuffer);
}
+ if (written > 0) {
+ mFramesWritten += written / mFrameSize;
+ }
return written;
}
@@ -1923,6 +1936,7 @@
requested = &timeout;
}
+ size_t writtenFrames = 0;
while (mRemainingFrames > 0) {
Buffer audioBuffer;
@@ -2024,6 +2038,7 @@
}
releaseBuffer(&audioBuffer);
+ writtenFrames += releasedFrames;
// FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer
// if callback doesn't like to accept the full chunk
@@ -2047,6 +2062,10 @@
#endif
}
+ if (writtenFrames > 0) {
+ AutoMutex lock(mLock);
+ mFramesWritten += writtenFrames;
+ }
mRemainingFrames = notificationFrames;
mRetryOnPartialBuffer = true;
@@ -2109,6 +2128,7 @@
}
if (mState == STATE_ACTIVE) {
result = mAudioTrack->start();
+ mFramesWrittenServerOffset = mFramesWritten; // server resets to zero so we offset
}
}
if (result != NO_ERROR) {
@@ -2162,6 +2182,47 @@
return mAudioTrack->setParameters(keyValuePairs);
}
+status_t AudioTrack::getTimestamp(ExtendedTimestamp *timestamp)
+{
+ if (timestamp == nullptr) {
+ return BAD_VALUE;
+ }
+ AutoMutex lock(mLock);
+ return getTimestamp_l(timestamp);
+}
+
+status_t AudioTrack::getTimestamp_l(ExtendedTimestamp *timestamp)
+{
+ if (mCblk->mFlags & CBLK_INVALID) {
+ const status_t status = restoreTrack_l("getTimestampExtended");
+ if (status != OK) {
+ // per getTimestamp() API doc in header, we return DEAD_OBJECT here,
+ // recommending that the track be recreated.
+ return DEAD_OBJECT;
+ }
+ }
+ // check for offloaded/direct here in case restoring somehow changed those flags.
+ if (isOffloadedOrDirect_l()) {
+ return INVALID_OPERATION; // not supported
+ }
+ status_t status = mProxy->getTimestamp(timestamp);
+ bool found = false;
+ if (status == OK) {
+ timestamp->mPosition[ExtendedTimestamp::LOCATION_CLIENT] = mFramesWritten;
+ timestamp->mTimeNs[ExtendedTimestamp::LOCATION_CLIENT] = 0;
+ // server side frame offset in case AudioTrack has been restored.
+ for (int i = ExtendedTimestamp::LOCATION_SERVER;
+ i < ExtendedTimestamp::LOCATION_MAX; ++i) {
+ if (timestamp->mTimeNs[i] >= 0) {
+ // apply server offset and the "flush frame correction here"
+ timestamp->mPosition[i] += mFramesWrittenServerOffset + timestamp->mFlushed;
+ found = true;
+ }
+ }
+ }
+ return found ? OK : WOULD_BLOCK;
+}
+
status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp)
{
AutoMutex lock(mLock);
@@ -2459,6 +2520,56 @@
return NO_ERROR;
}
+status_t AudioTrack::pendingDuration(int32_t *msec, ExtendedTimestamp::Location location)
+{
+ if (msec == nullptr ||
+ (location != ExtendedTimestamp::LOCATION_SERVER
+ && location != ExtendedTimestamp::LOCATION_KERNEL)) {
+ return BAD_VALUE;
+ }
+ AutoMutex lock(mLock);
+ // inclusive of offloaded and direct tracks.
+ //
+ // It is possible, but not enabled, to allow duration computation for non-pcm
+ // audio_has_proportional_frames() formats because currently they have
+ // the drain rate equivalent to the pcm sample rate * framesize.
+ if (!isPurePcmData_l()) {
+ return INVALID_OPERATION;
+ }
+ ExtendedTimestamp ets;
+ if (getTimestamp_l(&ets) == OK
+ && ets.mTimeNs[location] > 0) {
+ int64_t diff = ets.mPosition[ExtendedTimestamp::LOCATION_CLIENT]
+ - ets.mPosition[location];
+ if (diff < 0) {
+ *msec = 0;
+ } else {
+ // ms is the playback time by frames
+ int64_t ms = (int64_t)((double)diff * 1000 /
+ ((double)mSampleRate * mPlaybackRate.mSpeed));
+ // clockdiff is the timestamp age (negative)
+ int64_t clockdiff = (mState != STATE_ACTIVE) ? 0 :
+ ets.mTimeNs[location]
+ + ets.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_MONOTONIC]
+ - systemTime(SYSTEM_TIME_MONOTONIC);
+
+ //ALOGV("ms: %lld clockdiff: %lld", (long long)ms, (long long)clockdiff);
+ static const int NANOS_PER_MILLIS = 1000000;
+ *msec = (int32_t)(ms + clockdiff / NANOS_PER_MILLIS);
+ }
+ return NO_ERROR;
+ }
+ if (location != ExtendedTimestamp::LOCATION_SERVER) {
+ return INVALID_OPERATION; // LOCATION_KERNEL is not available
+ }
+ // use server position directly (offloaded and direct arrive here)
+ updateAndGetPosition_l();
+ int32_t diff = (Modulo<uint32_t>(mFramesWritten) - mPosition).signedValue();
+ *msec = (diff <= 0) ? 0
+ : (int32_t)((double)diff * 1000 / ((double)mSampleRate * mPlaybackRate.mSpeed));
+ return NO_ERROR;
+}
+
// =========================================================================
void AudioTrack::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 2396d87..7119517 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -615,7 +615,7 @@
ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
size_t frameSize, bool isOut, bool clientInServer)
: Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer),
- mAvailToClient(0), mFlush(0), mReleased(0)
+ mAvailToClient(0), mFlush(0), mReleased(0), mFlushed(0)
, mTimestampMutator(&cblk->mExtendedTimestampQueue)
{
cblk->mBufferSizeInFrames = frameCount;
@@ -671,6 +671,7 @@
mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);
}
}
+ mFlushed += (newFront - front) & mask;
front = newFront;
}
} else {
diff --git a/media/libmedia/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp
index 8376c0a..84f1181 100644
--- a/media/libmedia/IMediaSource.cpp
+++ b/media/libmedia/IMediaSource.cpp
@@ -295,13 +295,19 @@
mGroup->add_buffer(new MediaBuffer(allocateSize));
}
+ MediaBuffer *newBuf = NULL;
ret = mGroup->acquire_buffer(
- &transferBuf, false /* nonBlocking */, usedSize);
- if (ret != OK || transferBuf == NULL || transferBuf->mMemory == NULL) {
+ &newBuf, false /* nonBlocking */, usedSize);
+ if (ret != OK || newBuf == NULL || newBuf->mMemory == NULL) {
ALOGW("failed to acquire shared memory, ret %d", ret);
+ buf->release();
+ if (newBuf != NULL) {
+ newBuf->release();
+ }
reply->writeInt32(NULL_BUFFER);
return NO_ERROR;
}
+ transferBuf = newBuf;
memcpy(transferBuf->data(), (uint8_t*)buf->data() + buf->range_offset(),
buf->range_length());
offset = 0;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 0025660..251fc53 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1578,7 +1578,19 @@
}
if ((mRecycledTrack->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) {
- mRecycledTrack->flush();
+ int32_t msec = 0;
+ if (!mRecycledTrack->stopped()) { // check if active
+ (void)mRecycledTrack->pendingDuration(&msec);
+ }
+ mRecycledTrack->stop(); // ensure full data drain
+ ALOGD("deleting recycled track, waiting for data drain (%d msec)", msec);
+ if (msec > 0) {
+ static const int32_t WAIT_LIMIT_MS = 3000;
+ if (msec > WAIT_LIMIT_MS) {
+ msec = WAIT_LIMIT_MS;
+ }
+ usleep(msec * 1000LL);
+ }
}
// An offloaded track isn't flushed because the STREAM_END is reported
// slightly prematurely to allow time for the gapless track switch
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index baa95fa..08ac941 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -876,7 +876,7 @@
status_t NuPlayer::GenericSource::dequeueAccessUnit(
bool audio, sp<ABuffer> *accessUnit) {
- if (!mStarted) {
+ if (audio && !mStarted) {
return -EWOULDBLOCK;
}
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index d6a9f53..aebe479 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -3945,15 +3945,14 @@
h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
- }
-
- // XXX
- if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
- ALOGW("Use baseline profile instead of %d for AVC recording",
- h264type.eProfile);
+ } else {
+ // Use baseline profile for AVC recording if profile is not specified.
h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
}
+ ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
+ asString(h264type.eProfile), asString(h264type.eLevel));
+
if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
h264type.nSliceHeaderSpacing = 0;
h264type.bUseHadamard = OMX_TRUE;
@@ -3971,6 +3970,23 @@
h264type.bDirect8x8Inference = OMX_FALSE;
h264type.bDirectSpatialTemporal = OMX_FALSE;
h264type.nCabacInitIdc = 0;
+ } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
+ h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
+ h264type.nSliceHeaderSpacing = 0;
+ h264type.bUseHadamard = OMX_TRUE;
+ h264type.nRefFrames = 2;
+ h264type.nBFrames = 1;
+ h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
+ h264type.nAllowedPictureTypes =
+ OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
+ h264type.nRefIdx10ActiveMinus1 = 0;
+ h264type.nRefIdx11ActiveMinus1 = 0;
+ h264type.bEntropyCodingCABAC = OMX_TRUE;
+ h264type.bWeightedPPrediction = OMX_TRUE;
+ h264type.bconstIpred = OMX_TRUE;
+ h264type.bDirect8x8Inference = OMX_TRUE;
+ h264type.bDirectSpatialTemporal = OMX_TRUE;
+ h264type.nCabacInitIdc = 1;
}
if (h264type.nBFrames != 0) {
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
index e6303ba..bcbd78d 100644
--- a/media/libstagefright/CallbackDataSource.cpp
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -30,14 +30,15 @@
CallbackDataSource::CallbackDataSource(
const sp<IDataSource>& binderDataSource)
- : mIDataSource(binderDataSource) {
+ : mIDataSource(binderDataSource),
+ mIsClosed(false) {
// Set up the buffer to read into.
mMemory = mIDataSource->getIMemory();
}
CallbackDataSource::~CallbackDataSource() {
ALOGV("~CallbackDataSource");
- mIDataSource->close();
+ close();
}
status_t CallbackDataSource::initCheck() const {
@@ -99,6 +100,13 @@
return mIDataSource->getFlags();
}
+void CallbackDataSource::close() {
+ if (!mIsClosed) {
+ mIDataSource->close();
+ mIsClosed = true;
+ }
+}
+
TinyCacheSource::TinyCacheSource(const sp<DataSource>& source)
: mSource(source), mCachedOffset(0), mCachedSize(0) {
}
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index 5d762d8..5e0baa4 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -67,7 +67,7 @@
FileSource::~FileSource() {
if (mFd >= 0) {
- close(mFd);
+ ::close(mFd);
mFd = -1;
}
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 58bfa67..7a8f4c0 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -2550,8 +2550,8 @@
((timestampUs * mTimeScale + 500000LL) / 1000000LL -
(lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
if (currDurationTicks < 0ll) {
- ALOGE("timestampUs %" PRId64 " < lastTimestampUs %" PRId64 " for %s track",
- timestampUs, lastTimestampUs, trackName);
+ ALOGE("do not support out of order frames (timestamp: %lld < last: %lld for %s track",
+ (long long)timestampUs, (long long)lastTimestampUs, trackName);
copy->release();
mSource->stop();
return UNKNOWN_ERROR;
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 1acfca0..90c56f4 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -712,6 +712,9 @@
if (mStarted) {
ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio");
+ if (mIsVideo) {
+ mEncoder->requestIDRFrame();
+ }
if (mFlags & FLAG_USE_SURFACE_INPUT) {
resume();
} else {
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 6d1a460..cc38a12 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -55,6 +55,7 @@
}
mSelectedTracks.clear();
+ mDataSource->close();
}
status_t NuMediaExtractor::setDataSource(
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 7027780..c6e3571 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -61,6 +61,7 @@
StagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
ALOGV("~StagefrightMetadataRetriever()");
clearMetadata();
+ mSource->close();
}
status_t StagefrightMetadataRetriever::setDataSource(
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 520ecb4..1fc5995 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -767,31 +767,31 @@
* Thus, we could not say for sure whether a stream is
* AAC+/eAAC+ until the first data frame is decoded.
*/
- if (mInputBufferCount <= 2 || mOutputBufferCount > 1) { // TODO: <= 1
- if (mStreamInfo->sampleRate != prevSampleRate ||
- mStreamInfo->numChannels != prevNumChannels) {
- ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
- prevSampleRate, mStreamInfo->sampleRate,
- prevNumChannels, mStreamInfo->numChannels);
-
- notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
- mOutputPortSettingsChange = AWAITING_DISABLED;
-
- if (inHeader && inHeader->nFilledLen == 0) {
- inInfo->mOwnedByUs = false;
- mInputBufferCount++;
- inQueue.erase(inQueue.begin());
- mLastInHeader = NULL;
- inInfo = NULL;
- notifyEmptyBufferDone(inHeader);
- inHeader = NULL;
- }
+ if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
+ if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
+ ALOGW("Invalid AAC stream");
+ mSignalledError = true;
+ notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
return;
}
- } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
- ALOGW("Invalid AAC stream");
- mSignalledError = true;
- notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
+ } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
+ (mStreamInfo->numChannels != prevNumChannels)) {
+ ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
+ prevSampleRate, mStreamInfo->sampleRate,
+ prevNumChannels, mStreamInfo->numChannels);
+
+ notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+
+ if (inHeader && inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ mInputBufferCount++;
+ inQueue.erase(inQueue.begin());
+ mLastInHeader = NULL;
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
return;
}
if (inHeader && inHeader->nFilledLen == 0) {
@@ -826,10 +826,10 @@
while (mOutputDelayCompensated > 0) {
// a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
-
- // run DRC check
- mDrcWrap.submitStreamData(mStreamInfo);
- mDrcWrap.update();
+
+ // run DRC check
+ mDrcWrap.submitStreamData(mStreamInfo);
+ mDrcWrap.update();
AAC_DECODER_ERROR decoderErr =
aacDecoder_DecodeFrame(mAACDecoder,
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index 92f5c97..1e64b49 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -416,7 +416,7 @@
uint8_t *pBuf;
if (outHeader) {
if (outHeader->nAllocLen < sizeY + (sizeUV * 2)) {
- android_errorWriteLog(0x534e4554, "27569635");
+ android_errorWriteLog(0x534e4554, "27833616");
return false;
}
pBuf = outHeader->pBuffer;
diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
index a891514..7df6156 100644
--- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
+++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
@@ -377,7 +377,7 @@
uint8_t *pBuf;
if (outHeader) {
if (outHeader->nAllocLen < sizeY + (sizeUV * 2)) {
- android_errorWriteLog(0x534e4554, "27569635");
+ android_errorWriteLog(0x534e4554, "27833616");
return false;
}
pBuf = outHeader->pBuffer;
diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
index e134d38..8283ab5 100644
--- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
+++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
@@ -501,7 +501,7 @@
uint8_t *pBuf;
if (outHeader) {
if (outHeader->nAllocLen < sizeY + (sizeUV * 2)) {
- android_errorWriteLog(0x534e4554, "27569635");
+ android_errorWriteLog(0x534e4554, "27833616");
return false;
}
pBuf = outHeader->pBuffer;
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
index ad122de..2e44ed7 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
@@ -461,7 +461,7 @@
size_t frameSize = kMaxOpusOutputPacketSizeSamples;
if (frameSize > outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels) {
frameSize = outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels;
- android_errorWriteLog(0x534e4554, "27887390");
+ android_errorWriteLog(0x534e4554, "27833616");
}
int numFrames = opus_multistream_decode(mDecoder,
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index e1af9b9..f648bb3 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -276,7 +276,7 @@
size_t size = header->nFilledLen;
if (size < 7) {
ALOGE("Too small input buffer: %zu bytes", size);
- android_errorWriteLog(0x534e4554, "27887390");
+ android_errorWriteLog(0x534e4554, "27833616");
notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
mSignalledError = true;
return;
@@ -405,7 +405,7 @@
size_t numSamplesPerBuffer = kMaxNumSamplesPerBuffer;
if (numSamplesPerBuffer > outHeader->nAllocLen / sizeof(int16_t)) {
numSamplesPerBuffer = outHeader->nAllocLen / sizeof(int16_t);
- android_errorWriteLog(0x534e4554, "27887390");
+ android_errorWriteLog(0x534e4554, "27833616");
}
numFrames = vorbis_dsp_pcmout(
mState, (int16_t *)outHeader->pBuffer,
diff --git a/media/libstagefright/foundation/ANetworkSession.cpp b/media/libstagefright/foundation/ANetworkSession.cpp
index 4bcb1f6..46314eb 100644
--- a/media/libstagefright/foundation/ANetworkSession.cpp
+++ b/media/libstagefright/foundation/ANetworkSession.cpp
@@ -457,7 +457,7 @@
while (mInBuffer.size() >= 2) {
size_t offset = 2;
- unsigned payloadLen = data[1] & 0x7f;
+ uint64_t payloadLen = data[1] & 0x7f;
if (payloadLen == 126) {
if (offset + 2 > mInBuffer.size()) {
break;
@@ -485,7 +485,7 @@
offset += 4;
}
- if (offset + payloadLen > mInBuffer.size()) {
+ if (payloadLen > mInBuffer.size() || offset > mInBuffer.size() - payloadLen) {
break;
}
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 37847e3..0a1ed94 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -355,7 +355,11 @@
if (!n) {
return OK;
}
- CHECK(n % 16 == 0);
+
+ if (n < 16 || n % 16) {
+ ALOGE("not enough or trailing bytes (%zu) in encrypted buffer", n);
+ return ERROR_MALFORMED;
+ }
if (first) {
// If decrypting the first block in a file, read the iv from the manifest
diff --git a/media/libstagefright/include/CallbackDataSource.h b/media/libstagefright/include/CallbackDataSource.h
index 8c6fd8f..9b33810 100644
--- a/media/libstagefright/include/CallbackDataSource.h
+++ b/media/libstagefright/include/CallbackDataSource.h
@@ -37,10 +37,12 @@
virtual ssize_t readAt(off64_t offset, void *data, size_t size);
virtual status_t getSize(off64_t *size);
virtual uint32_t flags();
+ virtual void close();
private:
sp<IDataSource> mIDataSource;
sp<IMemory> mMemory;
+ bool mIsClosed;
DISALLOW_EVIL_CONSTRUCTORS(CallbackDataSource);
};
@@ -58,6 +60,7 @@
virtual ssize_t readAt(off64_t offset, void* data, size_t size);
virtual status_t getSize(off64_t* size);
virtual uint32_t flags();
+ virtual void close() { mSource->close(); }
private:
// 2kb comes from experimenting with the time-to-first-frame from a MediaPlayer
diff --git a/media/libstagefright/webm/EbmlUtil.cpp b/media/libstagefright/webm/EbmlUtil.cpp
index 449fec6..c519f5c 100644
--- a/media/libstagefright/webm/EbmlUtil.cpp
+++ b/media/libstagefright/webm/EbmlUtil.cpp
@@ -29,7 +29,9 @@
};
int numberOfTrailingZeros32(int32_t i) {
- uint32_t u = (i & -i) * 0x0450FBAF;
+ int64_t i64 = i;
+ i64 = (i64 & -i64) * 0x0450FBAF;
+ uint32_t u = i64;
return NTZ_TABLE[(u) >> 26];
}
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index 2cec5d2..1738df8 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -5,6 +5,7 @@
LOCAL_SRC_FILES := register.cpp
LOCAL_MODULE := libregistermsext
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := -Werror -Wall
include $(BUILD_STATIC_LIBRARY)
endif
@@ -39,4 +40,6 @@
LOCAL_INIT_RC := mediaserver.rc
+LOCAL_CFLAGS := -Werror -Wall
+
include $(BUILD_EXECUTABLE)
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index 2cb7cc7..50b490d 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -151,6 +151,7 @@
PRIORITY_FOREGROUND);
if (res != OK) {
ALOGE("Failed to start the looper");
+ AMediaCodec_delete(mData);
return NULL;
}
if (name_is_type) {
diff --git a/radio/Android.mk b/radio/Android.mk
index ecbb8fd..0377328 100644
--- a/radio/Android.mk
+++ b/radio/Android.mk
@@ -36,4 +36,6 @@
LOCAL_MODULE:= libradio
+LOCAL_CFLAGS := -Werror -Wall
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index b322a45..87374bc 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2531,6 +2531,10 @@
{
if (!mMasterMute) {
char value[PROPERTY_VALUE_MAX];
+ if (mOutDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
+ ALOGD("ro.audio.silent will be ignored for threads on AUDIO_DEVICE_OUT_REMOTE_SUBMIX");
+ return;
+ }
if (property_get("ro.audio.silent", value, "0") > 0) {
char *endptr;
unsigned long ul = strtoul(value, &endptr, 0);
@@ -2924,11 +2928,7 @@
break;
}
bool released = false;
- // The following works around a bug in the offload driver. Ideally we would release
- // the wake lock every time, but that causes the last offload buffer(s) to be
- // dropped while the device is on battery, so we need to hold a wake lock during
- // the drain phase.
- if (mBytesRemaining && !(mDrainSequence & 1)) {
+ if (!keepWakeLock()) {
releaseWakeLock_l();
released = true;
}
@@ -3162,20 +3162,23 @@
if ((mType == OFFLOAD) && !audio_has_proportional_frames(mFormat)) {
Mutex::Autolock _l(mLock);
if (!mSignalPending && !exitPending()) {
- // Do not sleep more than one buffer duration since last write and not
- // less than kDirectMinSleepTimeUs
+ // If more than one buffer has been written to the audio HAL since exiting
+ // standby or last flush, do not sleep more than one buffer duration
+ // since last write and not less than kDirectMinSleepTimeUs.
// Wake up if a command is received
- nsecs_t now = systemTime();
- uint32_t deltaUs = (uint32_t)((now - mLastWriteTime) / 1000);
uint32_t timeoutUs = mSleepTimeUs;
- if (timeoutUs + deltaUs > mBufferDurationUs) {
- if (mBufferDurationUs > deltaUs) {
- timeoutUs = mBufferDurationUs - deltaUs;
- if (timeoutUs < kDirectMinSleepTimeUs) {
+ if (mBytesWritten >= (int64_t) mBufferSize) {
+ nsecs_t now = systemTime();
+ uint32_t deltaUs = (uint32_t)((now - mLastWriteTime) / 1000);
+ if (timeoutUs + deltaUs > mBufferDurationUs) {
+ if (mBufferDurationUs > deltaUs) {
+ timeoutUs = mBufferDurationUs - deltaUs;
+ if (timeoutUs < kDirectMinSleepTimeUs) {
+ timeoutUs = kDirectMinSleepTimeUs;
+ }
+ } else {
timeoutUs = kDirectMinSleepTimeUs;
}
- } else {
- timeoutUs = kDirectMinSleepTimeUs;
}
}
mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)timeoutUs));
@@ -5165,10 +5168,11 @@
AudioStreamOut* output, audio_io_handle_t id, uint32_t device, bool systemReady,
uint32_t bitRate)
: DirectOutputThread(audioFlinger, output, id, device, OFFLOAD, systemReady, bitRate),
- mPausedBytesRemaining(0)
+ mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true)
{
//FIXME: mStandby should be set to true by ThreadBase constructor
mStandby = true;
+ mKeepWakeLock = property_get_bool("ro.audio.offload_wakelock", true /* default_value */);
}
void AudioFlinger::OffloadThread::threadLoop_exit()
@@ -5417,6 +5421,8 @@
mBytesRemaining = 0;
mPausedWriteLength = 0;
mPausedBytesRemaining = 0;
+ // reset bytes written count to reflect that DSP buffers are empty after flush.
+ mBytesWritten = 0;
if (mUseAsyncWrite) {
// discard any pending drain or write ack by incrementing sequence
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 761fc71..cf896e0 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -527,6 +527,8 @@
// ThreadBase virtuals
virtual void preExit();
+ virtual bool keepWakeLock() const { return true; }
+
public:
virtual status_t initCheck() const { return (mOutput == NULL) ? NO_INIT : NO_ERROR; }
@@ -996,9 +998,12 @@
virtual bool waitingAsyncCallback();
virtual bool waitingAsyncCallback_l();
+ virtual bool keepWakeLock() const { return mKeepWakeLock; }
+
private:
size_t mPausedWriteLength; // length in bytes of write interrupted by pause
size_t mPausedBytesRemaining; // bytes still waiting in mixbuffer after resume
+ bool mKeepWakeLock; // keep wake lock while waiting for write callback
};
class AsyncCallbackThread : public Thread {
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 7cbb6b8..00de4f0 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1113,6 +1113,9 @@
if (!checked) { // no server info, assume drained.
mAudioTrackServerProxy->setDrained(true);
}
+ // Set correction for flushed frames that are not accounted for in released.
+ // This is important for the new 64 bit timestamps which do not reset to 0 on flush.
+ local.mFlushed = mAudioTrackServerProxy->framesFlushed();
mServerProxy->setTimestamp(local);
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index d25dabd..35c868e 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3678,7 +3678,7 @@
mpClientInterface->setParameters(output, String8(param));
free(param);
}
- updateAudioProfiles(output, profile->getAudioProfiles());
+ updateAudioProfiles(device, output, profile->getAudioProfiles());
if (!profile->hasValidAudioProfile()) {
ALOGW("checkOutputsForDevice() missing param");
mpClientInterface->closeOutput(output);
@@ -3916,7 +3916,7 @@
mpClientInterface->setParameters(input, String8(param));
free(param);
}
- updateAudioProfiles(input, profile->getAudioProfiles());
+ updateAudioProfiles(device, input, profile->getAudioProfiles());
if (!profile->hasValidAudioProfile()) {
ALOGW("checkInputsForDevice() direct input missing param");
mpClientInterface->closeInput(input);
@@ -4936,7 +4936,7 @@
voiceVolume = 1.0;
}
- if (voiceVolume != mLastVoiceVolume && outputDesc == mPrimaryOutput) {
+ if (voiceVolume != mLastVoiceVolume) {
mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
mLastVoiceVolume = voiceVolume;
}
@@ -5210,15 +5210,14 @@
}
// Modify the list of surround sound formats supported.
-void AudioPolicyManager::filterSurroundFormats(FormatVector &formats) {
- // TODO Change the ALOGIs to ALOGVs in this function after the feature is verified.
-
+void AudioPolicyManager::filterSurroundFormats(FormatVector *formatsPtr) {
+ FormatVector &formats = *formatsPtr;
// TODO Set this based on Config properties.
const bool alwaysForceAC3 = true;
audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
- ALOGI("%s: forced use = %d", __FUNCTION__, forceUse);
+ ALOGD("%s: forced use = %d", __FUNCTION__, forceUse);
// Analyze original support for various formats.
bool supportsAC3 = false;
@@ -5226,7 +5225,6 @@
bool supportsIEC61937 = false;
for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
audio_format_t format = formats[formatIndex];
- ALOGI("%s: original formats: 0x%08x", __FUNCTION__, format);
switch (format) {
case AUDIO_FORMAT_AC3:
supportsAC3 = true;
@@ -5243,8 +5241,6 @@
break;
}
}
- ALOGI("%s: original, supportsAC3 = %d, supportsOtherSurround = %d, supportsIEC61937 = %d",
- __FUNCTION__, supportsAC3, supportsOtherSurround, supportsIEC61937);
// Modify formats based on surround preferences.
// If NEVER, remove support for surround formats.
@@ -5259,7 +5255,6 @@
case AUDIO_FORMAT_DTS:
case AUDIO_FORMAT_DTS_HD:
case AUDIO_FORMAT_IEC61937:
- ALOGI("%s: remove format 0x%08x", __FUNCTION__, format);
formats.removeAt(formatIndex);
break;
default:
@@ -5297,25 +5292,56 @@
supportsIEC61937 = true;
}
}
- // Just for debugging.
- for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
- audio_format_t format = formats[formatIndex];
- ALOGI("%s: final formats: 0x%08x", __FUNCTION__, format);
- }
- ALOGI("%s: final, supportsAC3 = %d, supportsOtherSurround = %d, supportsIEC61937 = %d",
- __FUNCTION__, supportsAC3, supportsOtherSurround, supportsIEC61937);
}
-void AudioPolicyManager::updateAudioProfiles(audio_io_handle_t ioHandle,
+// Modify the list of channel masks supported.
+void AudioPolicyManager::filterSurroundChannelMasks(ChannelsVector *channelMasksPtr) {
+ ChannelsVector &channelMasks = *channelMasksPtr;
+ audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
+ AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
+
+ // If NEVER, then remove support for channelMasks > stereo.
+ if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
+ for (size_t maskIndex = 0; maskIndex < channelMasks.size(); ) {
+ audio_channel_mask_t channelMask = channelMasks[maskIndex];
+ if (channelMask & ~AUDIO_CHANNEL_OUT_STEREO) {
+ ALOGI("%s: force NEVER, so remove channelMask 0x%08x", __FUNCTION__, channelMask);
+ channelMasks.removeAt(maskIndex);
+ } else {
+ maskIndex++;
+ }
+ }
+ // If ALWAYS, then make sure we at least support 5.1
+ } else if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
+ bool supports5dot1 = false;
+ // Are there any channel masks that can be considered "surround"?
+ for (size_t maskIndex = 0; maskIndex < channelMasks.size(); maskIndex++) {
+ audio_channel_mask_t channelMask = channelMasks[maskIndex];
+ if ((channelMask & AUDIO_CHANNEL_OUT_5POINT1) == AUDIO_CHANNEL_OUT_5POINT1) {
+ supports5dot1 = true;
+ break;
+ }
+ }
+ // If not then add 5.1 support.
+ if (!supports5dot1) {
+ channelMasks.add(AUDIO_CHANNEL_OUT_5POINT1);
+ ALOGI("%s: force ALWAYS, so adding channelMask for 5.1 surround", __FUNCTION__);
+ }
+ }
+}
+
+void AudioPolicyManager::updateAudioProfiles(audio_devices_t device,
+ audio_io_handle_t ioHandle,
AudioProfileVector &profiles)
{
String8 reply;
char *value;
+
// Format MUST be checked first to update the list of AudioProfile
if (profiles.hasDynamicFormat()) {
reply = mpClientInterface->getParameters(ioHandle,
String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
- ALOGI("%s: supported formats %s", __FUNCTION__, reply.string());
+ ALOGV("%s: supported formats %s", __FUNCTION__, reply.string());
AudioParameter repliedParameters(reply);
if (repliedParameters.get(
String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS), reply) != NO_ERROR) {
@@ -5323,7 +5349,9 @@
return;
}
FormatVector formats = formatsFromString(reply.string());
- filterSurroundFormats(formats);
+ if (device == AUDIO_DEVICE_OUT_HDMI) {
+ filterSurroundFormats(&formats);
+ }
profiles.setFormats(formats);
}
const FormatVector &supportedFormats = profiles.getSupportedFormats();
@@ -5355,6 +5383,9 @@
if (repliedParameters.get(
String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS), reply) == NO_ERROR) {
channelMasks = channelMasksFromString(reply.string());
+ if (device == AUDIO_DEVICE_OUT_HDMI) {
+ filterSurroundChannelMasks(&channelMasks);
+ }
}
}
profiles.addProfileFromHal(new AudioProfile(format, channelMasks, samplingRates));
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 1ef896f..0420679 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -586,10 +586,12 @@
AudioPolicyManagerInterface *mEngine;
private:
// Add or remove AC3 DTS encodings based on user preferences.
- void filterSurroundFormats(FormatVector &formats);
+ void filterSurroundFormats(FormatVector *formatsPtr);
+ void filterSurroundChannelMasks(ChannelsVector *channelMasksPtr);
// If any, resolve any "dynamic" fields of an Audio Profiles collection
- void updateAudioProfiles(audio_io_handle_t ioHandle, AudioProfileVector &profiles);
+ void updateAudioProfiles(audio_devices_t device, audio_io_handle_t ioHandle,
+ AudioProfileVector &profiles);
// updates device caching and output for streams that can influence the
// routing of notifications
diff --git a/soundtrigger/Android.mk b/soundtrigger/Android.mk
index d91c4c2..c794cc1 100644
--- a/soundtrigger/Android.mk
+++ b/soundtrigger/Android.mk
@@ -35,4 +35,6 @@
LOCAL_MODULE:= libsoundtrigger
+LOCAL_CFLAGS := -Werror -Wall
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/tools/resampler_tools/Android.mk b/tools/resampler_tools/Android.mk
index b58e4cd..bba5199 100644
--- a/tools/resampler_tools/Android.mk
+++ b/tools/resampler_tools/Android.mk
@@ -12,6 +12,6 @@
LOCAL_MODULE := fir
+LOCAL_CFLAGS := -Werror -Wall
+
include $(BUILD_HOST_EXECUTABLE)
-
-