Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 636a5bd6 authored by Eino-Ville Talvala's avatar Eino-Ville Talvala Committed by Android (Google) Code Review
Browse files

Merge "Camera: Add output side to camera3 HAL device" into jb-mr2-dev

parents 3a1d8b51 d0158c38
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -145,9 +145,10 @@ Camera2Client::~Camera2Client() {


status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
    String8 result;
    String8 result;
    result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
    result.appendFormat("Client2[%d] (%p) Client: %s PID: %d, dump:\n",
            mCameraId,
            mCameraId,
            getRemoteCallback()->asBinder().get(),
            getRemoteCallback()->asBinder().get(),
            String8(mClientPackageName).string(),
            mClientPid);
            mClientPid);
    result.append("  State: ");
    result.append("  State: ");
#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
+190 −15
Original line number Original line Diff line number Diff line
@@ -38,7 +38,8 @@ namespace android {
Camera3Device::Camera3Device(int id):
Camera3Device::Camera3Device(int id):
        mId(id),
        mId(id),
        mHal3Device(NULL),
        mHal3Device(NULL),
        mStatus(STATUS_UNINITIALIZED)
        mStatus(STATUS_UNINITIALIZED),
        mListener(NULL)
{
{
    ATRACE_CALL();
    ATRACE_CALL();
    camera3_callback_ops::notify = &sNotify;
    camera3_callback_ops::notify = &sNotify;
@@ -652,32 +653,53 @@ status_t Camera3Device::waitUntilDrainedLocked() {


status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
    ATRACE_CALL();
    ATRACE_CALL();
    (void)listener;
    Mutex::Autolock l(mOutputLock);


    ALOGE("%s: Unimplemented", __FUNCTION__);
    if (listener != NULL && mListener != NULL) {
    return INVALID_OPERATION;
        ALOGW("%s: Replacing old callback listener", __FUNCTION__);
    }
    mListener = listener;

    return OK;
}
}


status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
    (void)timeout;
    ATRACE_CALL();
    status_t res;
    Mutex::Autolock l(mOutputLock);


    ALOGE("%s: Unimplemented", __FUNCTION__);
    while (mResultQueue.empty()) {
    return INVALID_OPERATION;
        res = mResultSignal.waitRelative(mOutputLock, timeout);
        if (res == TIMED_OUT) {
            return res;
        } else if (res != OK) {
            ALOGE("%s: Camera %d: Error waiting for frame: %s (%d)",
                    __FUNCTION__, mId, strerror(-res), res);
            return res;
        }
    }
    return OK;
}
}


status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
    ATRACE_CALL();
    ATRACE_CALL();
    (void)frame;
    Mutex::Autolock l(mOutputLock);


    ALOGE("%s: Unimplemented", __FUNCTION__);
    if (mResultQueue.empty()) {
    return INVALID_OPERATION;
        return NOT_ENOUGH_DATA;
    }

    CameraMetadata &result = *(mResultQueue.begin());
    frame->acquire(result);
    mResultQueue.erase(mResultQueue.begin());

    return OK;
}
}


status_t Camera3Device::triggerAutofocus(uint32_t id) {
status_t Camera3Device::triggerAutofocus(uint32_t id) {
    ATRACE_CALL();
    ATRACE_CALL();
    (void)id;
    (void)id;



    ALOGE("%s: Unimplemented", __FUNCTION__);
    ALOGE("%s: Unimplemented", __FUNCTION__);
    return INVALID_OPERATION;
    return INVALID_OPERATION;
}
}
@@ -853,15 +875,168 @@ status_t Camera3Device::configureStreamsLocked() {
 */
 */


void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
    (void)result;
    ATRACE_CALL();

    status_t res;

    if (result->result == NULL) {
        // TODO: Report error upstream
        ALOGW("%s: No metadata for frame %d", __FUNCTION__,
                result->frame_number);
        return;
    }

    nsecs_t timestamp = 0;
    AlgState cur3aState;
    AlgState new3aState;
    int32_t aeTriggerId = 0;
    int32_t afTriggerId = 0;

    NotificationListener *listener;

    {
        Mutex::Autolock l(mOutputLock);

        // Push result metadata into queue
        mResultQueue.push_back(CameraMetadata());
        CameraMetadata &captureResult = *(mResultQueue.end());

        captureResult = result->result;
        captureResult.update(ANDROID_REQUEST_FRAME_COUNT,
                (int32_t*)&result->frame_number, 1);

        // Get timestamp from result metadata

        camera_metadata_entry entry =
                captureResult.find(ANDROID_SENSOR_TIMESTAMP);
        if (entry.count == 0) {
            ALOGE("%s: Camera %d: No timestamp provided by HAL for frame %d!",
                    __FUNCTION__, mId, result->frame_number);
            // TODO: Report error upstream
        } else {
            timestamp = entry.data.i64[0];
        }

        // Get 3A states from result metadata

        entry = captureResult.find(ANDROID_CONTROL_AE_STATE);
        if (entry.count == 0) {
            ALOGE("%s: Camera %d: No AE state provided by HAL for frame %d!",
                    __FUNCTION__, mId, result->frame_number);
        } else {
            new3aState.aeState =
                    static_cast<camera_metadata_enum_android_control_ae_state>(
                        entry.data.u8[0]);
        }

        entry = captureResult.find(ANDROID_CONTROL_AF_STATE);
        if (entry.count == 0) {
            ALOGE("%s: Camera %d: No AF state provided by HAL for frame %d!",
                    __FUNCTION__, mId, result->frame_number);
        } else {
            new3aState.afState =
                    static_cast<camera_metadata_enum_android_control_af_state>(
                        entry.data.u8[0]);
        }

        entry = captureResult.find(ANDROID_CONTROL_AWB_STATE);
        if (entry.count == 0) {
            ALOGE("%s: Camera %d: No AWB state provided by HAL for frame %d!",
                    __FUNCTION__, mId, result->frame_number);
        } else {
            new3aState.awbState =
                    static_cast<camera_metadata_enum_android_control_awb_state>(
                        entry.data.u8[0]);
        }

        entry = captureResult.find(ANDROID_CONTROL_AF_TRIGGER_ID);
        if (entry.count == 0) {
            ALOGE("%s: Camera %d: No AF trigger ID provided by HAL for frame %d!",
                    __FUNCTION__, mId, result->frame_number);
        } else {
            afTriggerId = entry.data.i32[0];
        }

        entry = captureResult.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
        if (entry.count == 0) {
            ALOGE("%s: Camera %d: No AE precapture trigger ID provided by HAL"
                    " for frame %d!", __FUNCTION__, mId, result->frame_number);
        } else {
            aeTriggerId = entry.data.i32[0];
        }

        listener = mListener;
        cur3aState = m3AState;

        m3AState = new3aState;
    } // scope for mOutputLock

    // Return completed buffers to their streams
    for (size_t i = 0; i < result->num_output_buffers; i++) {
        Camera3Stream *stream =
                Camera3Stream::cast(result->output_buffers[i].stream);
        res = stream->returnBuffer(result->output_buffers[i], timestamp);
        // Note: stream may be deallocated at this point, if this buffer was the
        // last reference to it.
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't return buffer %d for frame %d to its"
                    "  stream:%s (%d)",  __FUNCTION__, mId, i,
                    result->frame_number, strerror(-res), res);
            // TODO: Report error upstream
        }
    }

    // Dispatch any 3A change events to listeners
    if (listener != NULL) {
        if (new3aState.aeState != cur3aState.aeState) {
            listener->notifyAutoExposure(new3aState.aeState, aeTriggerId);
        }
        if (new3aState.afState != cur3aState.afState) {
            listener->notifyAutoFocus(new3aState.afState, afTriggerId);
        }
        if (new3aState.awbState != cur3aState.awbState) {
            listener->notifyAutoWhitebalance(new3aState.awbState, aeTriggerId);
        }
    }


    ALOGE("%s: Unimplemented", __FUNCTION__);
}
}


void Camera3Device::notify(const camera3_notify_msg *msg) {
void Camera3Device::notify(const camera3_notify_msg *msg) {
    (void)msg;
    NotificationListener *listener;
    {
        Mutex::Autolock l(mOutputLock);
        if (mListener == NULL) return;
        listener = mListener;
    }


    ALOGE("%s: Unimplemented", __FUNCTION__);
    if (msg == NULL) {
        ALOGE("%s: Camera %d: HAL sent NULL notify message!",
                __FUNCTION__, mId);
        return;
    }

    switch (msg->type) {
        case CAMERA3_MSG_ERROR: {
            int streamId = 0;
            if (msg->message.error.error_stream != NULL) {
                Camera3Stream *stream =
                        Camera3Stream::cast(
                                  msg->message.error.error_stream);
                streamId = stream->getId();
            }
            listener->notifyError(msg->message.error.error_code,
                    msg->message.error.frame_number, streamId);
            break;
        }
        case CAMERA3_MSG_SHUTTER: {
            listener->notifyShutter(msg->message.shutter.frame_number,
                    msg->message.shutter.timestamp);
            break;
        }
        default:
            ALOGE("%s: Camera %d: Unknown notify message from HAL: %d",
                    __FUNCTION__, mId, msg->type);
    }
}
}


/**
/**
+27 −0
Original line number Original line Diff line number Diff line
@@ -254,6 +254,33 @@ class Camera3Device :
    };
    };
    sp<RequestThread> mRequestThread;
    sp<RequestThread> mRequestThread;


    /**
     * Output result queue and current HAL device 3A state
     */

    // Lock for output side of device
    Mutex                  mOutputLock;

    /**** Scope for mOutputLock ****/

    List<CameraMetadata>   mResultQueue;
    Condition              mResultSignal;
    NotificationListener  *mListener;

    struct AlgState {
        camera_metadata_enum_android_control_ae_state  aeState;
        camera_metadata_enum_android_control_af_state  afState;
        camera_metadata_enum_android_control_awb_state awbState;

        AlgState() :
                aeState(ANDROID_CONTROL_AE_STATE_INACTIVE),
                afState(ANDROID_CONTROL_AF_STATE_INACTIVE),
                awbState(ANDROID_CONTROL_AWB_STATE_INACTIVE) {
        }
    } m3AState;

    /**** End scope for mOutputLock ****/

    /**
    /**
     * Callback functions from HAL device
     * Callback functions from HAL device
     */
     */