/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "Camera2-CallbackProcessor"
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0

#include <utils/Log.h>
#include <utils/Trace.h>
#include <gui/Surface.h>

#include "common/CameraDeviceBase.h"
#include "api1/Camera2Client.h"
#include "api1/client2/CallbackProcessor.h"

#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )

namespace android {
namespace camera2 {

CallbackProcessor::CallbackProcessor(sp<Camera2Client> client):
        Thread(false),
        mClient(client),
        mDevice(client->getCameraDevice()),
        mId(client->getCameraId()),
        mCallbackAvailable(false),
        mCallbackToApp(false),
        mCallbackStreamId(NO_STREAM) {
}

CallbackProcessor::~CallbackProcessor() {
    ALOGV("%s: Exit", __FUNCTION__);
    deleteStream();
}

void CallbackProcessor::onFrameAvailable(const BufferItem& /*item*/) {
    Mutex::Autolock l(mInputMutex);
    if (!mCallbackAvailable) {
        mCallbackAvailable = true;
        mCallbackAvailableSignal.signal();
    }
}

status_t CallbackProcessor::setCallbackWindow(
        sp<ANativeWindow> callbackWindow) {
    ATRACE_CALL();
    status_t res;

    Mutex::Autolock l(mInputMutex);

    sp<Camera2Client> client = mClient.promote();
    if (client == 0) return OK;
    sp<CameraDeviceBase> device = client->getCameraDevice();

    // If the window is changing, clear out stream if it already exists
    if (mCallbackWindow != callbackWindow && mCallbackStreamId != NO_STREAM) {
        res = device->deleteStream(mCallbackStreamId);
        if (res != OK) {
            ALOGE("%s: Camera %d: Unable to delete old stream "
                    "for callbacks: %s (%d)", __FUNCTION__,
                    client->getCameraId(), strerror(-res), res);
            return res;
        }
        mCallbackStreamId = NO_STREAM;
        mCallbackConsumer.clear();
    }
    mCallbackWindow = callbackWindow;
    mCallbackToApp = (mCallbackWindow != NULL);

    return OK;
}

status_t CallbackProcessor::updateStream(const Parameters &params) {
    ATRACE_CALL();
    status_t res;

    Mutex::Autolock l(mInputMutex);

    sp<CameraDeviceBase> device = mDevice.promote();
    if (device == 0) {
        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
        return INVALID_OPERATION;
    }

    // If possible, use the flexible YUV format
    int32_t callbackFormat = params.previewFormat;
    if (mCallbackToApp) {
        // TODO: etalvala: This should use the flexible YUV format as well, but
        // need to reconcile HAL2/HAL3 requirements.
        callbackFormat = HAL_PIXEL_FORMAT_YV12;
    } else if(params.fastInfo.useFlexibleYuv &&
            (params.previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
             params.previewFormat == HAL_PIXEL_FORMAT_YV12) ) {
        callbackFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
    }

    if (!mCallbackToApp && mCallbackConsumer == 0) {
        // Create CPU buffer queue endpoint, since app hasn't given us one
        // Make it async to avoid disconnect deadlocks
        sp<IGraphicBufferProducer> producer;
        sp<IGraphicBufferConsumer> consumer;
        BufferQueue::createBufferQueue(&producer, &consumer);
        mCallbackConsumer = new CpuConsumer(consumer, kCallbackHeapCount);
        mCallbackConsumer->setFrameAvailableListener(this);
        mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
        mCallbackWindow = new Surface(producer);
    }

    if (mCallbackStreamId != NO_STREAM) {
        // Check if stream parameters have to change
        uint32_t currentWidth, currentHeight, currentFormat;
        res = device->getStreamInfo(mCallbackStreamId,
                &currentWidth, &currentHeight, &currentFormat);
        if (res != OK) {
            ALOGE("%s: Camera %d: Error querying callback output stream info: "
                    "%s (%d)", __FUNCTION__, mId,
                    strerror(-res), res);
            return res;
        }
        if (currentWidth != (uint32_t)params.previewWidth ||
                currentHeight != (uint32_t)params.previewHeight ||
                currentFormat != (uint32_t)callbackFormat) {
            // Since size should only change while preview is not running,
            // assuming that all existing use of old callback stream is
            // completed.
            ALOGV("%s: Camera %d: Deleting stream %d since the buffer "
                    "parameters changed", __FUNCTION__, mId, mCallbackStreamId);
            res = device->deleteStream(mCallbackStreamId);
            if (res != OK) {
                ALOGE("%s: Camera %d: Unable to delete old output stream "
                        "for callbacks: %s (%d)", __FUNCTION__,
                        mId, strerror(-res), res);
                return res;
            }
            mCallbackStreamId = NO_STREAM;
        }
    }

    if (mCallbackStreamId == NO_STREAM) {
        ALOGV("Creating callback stream: %d x %d, format 0x%x, API format 0x%x",
                params.previewWidth, params.previewHeight,
                callbackFormat, params.previewFormat);
        res = device->createStream(mCallbackWindow,
                params.previewWidth, params.previewHeight,
                callbackFormat, &mCallbackStreamId);
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
                    "%s (%d)", __FUNCTION__, mId,
                    strerror(-res), res);
            return res;
        }
    }

    return OK;
}

status_t CallbackProcessor::deleteStream() {
    ATRACE_CALL();
    sp<CameraDeviceBase> device;
    status_t res;
    {
        Mutex::Autolock l(mInputMutex);

        if (mCallbackStreamId == NO_STREAM) {
            return OK;
        }
        device = mDevice.promote();
        if (device == 0) {
            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
            return INVALID_OPERATION;
        }
    }
    res = device->waitUntilDrained();
    if (res != OK) {
        ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
                __FUNCTION__, strerror(-res), res);
        return res;
    }

    res = device->deleteStream(mCallbackStreamId);
    if (res != OK) {
        ALOGE("%s: Unable to delete callback stream: %s (%d)",
                __FUNCTION__, strerror(-res), res);
        return res;
    }

    {
        Mutex::Autolock l(mInputMutex);

        mCallbackHeap.clear();
        mCallbackWindow.clear();
        mCallbackConsumer.clear();

        mCallbackStreamId = NO_STREAM;
    }
    return OK;
}

int CallbackProcessor::getStreamId() const {
    Mutex::Autolock l(mInputMutex);
    return mCallbackStreamId;
}

void CallbackProcessor::dump(int /*fd*/, const Vector<String16>& /*args*/) const {
}

bool CallbackProcessor::threadLoop() {
    status_t res;

    {
        Mutex::Autolock l(mInputMutex);
        while (!mCallbackAvailable) {
            res = mCallbackAvailableSignal.waitRelative(mInputMutex,
                    kWaitDuration);
            if (res == TIMED_OUT) return true;
        }
        mCallbackAvailable = false;
    }

    do {
        sp<Camera2Client> client = mClient.promote();
        if (client == 0) {
            res = discardNewCallback();
        } else {
            res = processNewCallback(client);
        }
    } while (res == OK);

    return true;
}

status_t CallbackProcessor::discardNewCallback() {
    ATRACE_CALL();
    status_t res;
    CpuConsumer::LockedBuffer imgBuffer;
    res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
    if (res != OK) {
        if (res != BAD_VALUE) {
            ALOGE("%s: Camera %d: Error receiving next callback buffer: "
                    "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
        }
        return res;
    }
    mCallbackConsumer->unlockBuffer(imgBuffer);
    return OK;
}

status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) {
    ATRACE_CALL();
    status_t res;

    sp<Camera2Heap> callbackHeap;
    bool useFlexibleYuv = false;
    int32_t previewFormat = 0;
    size_t heapIdx;

    {
        /* acquire SharedParameters before mMutex so we don't dead lock
            with Camera2Client code calling into StreamingProcessor */
        SharedParameters::Lock l(client->getParameters());
        Mutex::Autolock m(mInputMutex);
        CpuConsumer::LockedBuffer imgBuffer;
        if (mCallbackStreamId == NO_STREAM) {
            ALOGV("%s: Camera %d:No stream is available"
                    , __FUNCTION__, mId);
            return INVALID_OPERATION;
        }

        ALOGV("%s: Getting buffer", __FUNCTION__);
        res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
        if (res != OK) {
            if (res != BAD_VALUE) {
                ALOGE("%s: Camera %d: Error receiving next callback buffer: "
                        "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
            }
            return res;
        }
        ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__,
                mId);

        if ( l.mParameters.state != Parameters::PREVIEW
                && l.mParameters.state != Parameters::RECORD
                && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
            ALOGV("%s: Camera %d: No longer streaming",
                    __FUNCTION__, mId);
            mCallbackConsumer->unlockBuffer(imgBuffer);
            return OK;
        }

        if (! (l.mParameters.previewCallbackFlags &
                CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
            ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
            mCallbackConsumer->unlockBuffer(imgBuffer);
            return OK;
        }
        if ((l.mParameters.previewCallbackFlags &
                        CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
                !l.mParameters.previewCallbackOneShot) {
            ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
            mCallbackConsumer->unlockBuffer(imgBuffer);
            return OK;
        }

        if (imgBuffer.width != static_cast<uint32_t>(l.mParameters.previewWidth) ||
                imgBuffer.height != static_cast<uint32_t>(l.mParameters.previewHeight)) {
            ALOGW("%s: The preview size has changed to %d x %d from %d x %d, this buffer is"
                    " no longer valid, dropping",__FUNCTION__,
                    l.mParameters.previewWidth, l.mParameters.previewHeight,
                    imgBuffer.width, imgBuffer.height);
            mCallbackConsumer->unlockBuffer(imgBuffer);
            return OK;
        }

        previewFormat = l.mParameters.previewFormat;
        useFlexibleYuv = l.mParameters.fastInfo.useFlexibleYuv &&
                (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
                 previewFormat == HAL_PIXEL_FORMAT_YV12);

        int32_t expectedFormat = useFlexibleYuv ?
                HAL_PIXEL_FORMAT_YCbCr_420_888 : previewFormat;

        if (imgBuffer.format != expectedFormat) {
            ALOGE("%s: Camera %d: Unexpected format for callback: "
                    "0x%x, expected 0x%x", __FUNCTION__, mId,
                    imgBuffer.format, expectedFormat);
            mCallbackConsumer->unlockBuffer(imgBuffer);
            return INVALID_OPERATION;
        }

        // In one-shot mode, stop sending callbacks after the first one
        if (l.mParameters.previewCallbackFlags &
                CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
            ALOGV("%s: clearing oneshot", __FUNCTION__);
            l.mParameters.previewCallbackOneShot = false;
        }

        uint32_t destYStride = 0;
        uint32_t destCStride = 0;
        if (useFlexibleYuv) {
            if (previewFormat == HAL_PIXEL_FORMAT_YV12) {
                // Strides must align to 16 for YV12
                destYStride = ALIGN(imgBuffer.width, 16);
                destCStride = ALIGN(destYStride / 2, 16);
            } else {
                // No padding for NV21
                ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP,
                        "Unexpected preview format 0x%x", previewFormat);
                destYStride = imgBuffer.width;
                destCStride = destYStride / 2;
            }
        } else {
            destYStride = imgBuffer.stride;
            // don't care about cStride
        }

        size_t bufferSize = Camera2Client::calculateBufferSize(
                imgBuffer.width, imgBuffer.height,
                previewFormat, destYStride);
        size_t currentBufferSize = (mCallbackHeap == 0) ?
                0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
        if (bufferSize != currentBufferSize) {
            mCallbackHeap.clear();
            mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
                    "Camera2Client::CallbackHeap");
            if (mCallbackHeap->mHeap->getSize() == 0) {
                ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
                        __FUNCTION__, mId);
                mCallbackConsumer->unlockBuffer(imgBuffer);
                return INVALID_OPERATION;
            }

            mCallbackHeapHead = 0;
            mCallbackHeapFree = kCallbackHeapCount;
        }

        if (mCallbackHeapFree == 0) {
            ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
                    __FUNCTION__, mId);
            mCallbackConsumer->unlockBuffer(imgBuffer);
            return OK;
        }

        heapIdx = mCallbackHeapHead;

        mCallbackHeapHead = (mCallbackHeapHead + 1) % kCallbackHeapCount;
        mCallbackHeapFree--;

        // TODO: Get rid of this copy by passing the gralloc queue all the way
        // to app

        ssize_t offset;
        size_t size;
        sp<IMemoryHeap> heap =
                mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
                        &size);
        uint8_t *data = (uint8_t*)heap->getBase() + offset;

        if (!useFlexibleYuv) {
            // Can just memcpy when HAL format matches API format
            memcpy(data, imgBuffer.data, bufferSize);
        } else {
            res = convertFromFlexibleYuv(previewFormat, data, imgBuffer,
                    destYStride, destCStride);
            if (res != OK) {
                ALOGE("%s: Camera %d: Can't convert between 0x%x and 0x%x formats!",
                        __FUNCTION__, mId, imgBuffer.format, previewFormat);
                mCallbackConsumer->unlockBuffer(imgBuffer);
                return BAD_VALUE;
            }
        }

        ALOGV("%s: Freeing buffer", __FUNCTION__);
        mCallbackConsumer->unlockBuffer(imgBuffer);

        // mCallbackHeap may get freed up once input mutex is released
        callbackHeap = mCallbackHeap;
    }

    // Call outside parameter lock to allow re-entrancy from notification
    {
        Camera2Client::SharedCameraCallbacks::Lock
            l(client->mSharedCameraCallbacks);
        if (l.mRemoteCallback != 0) {
            ALOGV("%s: Camera %d: Invoking client data callback",
                    __FUNCTION__, mId);
            l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
                    callbackHeap->mBuffers[heapIdx], NULL);
        }
    }

    // Only increment free if we're still using the same heap
    mCallbackHeapFree++;

    ALOGV("%s: exit", __FUNCTION__);

    return OK;
}

status_t CallbackProcessor::convertFromFlexibleYuv(int32_t previewFormat,
        uint8_t *dst,
        const CpuConsumer::LockedBuffer &src,
        uint32_t dstYStride,
        uint32_t dstCStride) const {

    if (previewFormat != HAL_PIXEL_FORMAT_YCrCb_420_SP &&
            previewFormat != HAL_PIXEL_FORMAT_YV12) {
        ALOGE("%s: Camera %d: Unexpected preview format when using "
                "flexible YUV: 0x%x", __FUNCTION__, mId, previewFormat);
        return INVALID_OPERATION;
    }

    // Copy Y plane, adjusting for stride
    const uint8_t *ySrc = src.data;
    uint8_t *yDst = dst;
    for (size_t row = 0; row < src.height; row++) {
        memcpy(yDst, ySrc, src.width);
        ySrc += src.stride;
        yDst += dstYStride;
    }

    // Copy/swizzle chroma planes, 4:2:0 subsampling
    const uint8_t *cbSrc = src.dataCb;
    const uint8_t *crSrc = src.dataCr;
    size_t chromaHeight = src.height / 2;
    size_t chromaWidth = src.width / 2;
    ssize_t chromaGap = src.chromaStride -
            (chromaWidth * src.chromaStep);
    size_t dstChromaGap = dstCStride - chromaWidth;

    if (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
        // Flexible YUV chroma to NV21 chroma
        uint8_t *crcbDst = yDst;
        // Check for shortcuts
        if (cbSrc == crSrc + 1 && src.chromaStep == 2) {
            ALOGV("%s: Fast NV21->NV21", __FUNCTION__);
            // Source has semiplanar CrCb chroma layout, can copy by rows
            for (size_t row = 0; row < chromaHeight; row++) {
                memcpy(crcbDst, crSrc, src.width);
                crcbDst += src.width;
                crSrc += src.chromaStride;
            }
        } else {
            ALOGV("%s: Generic->NV21", __FUNCTION__);
            // Generic copy, always works but not very efficient
            for (size_t row = 0; row < chromaHeight; row++) {
                for (size_t col = 0; col < chromaWidth; col++) {
                    *(crcbDst++) = *crSrc;
                    *(crcbDst++) = *cbSrc;
                    crSrc += src.chromaStep;
                    cbSrc += src.chromaStep;
                }
                crSrc += chromaGap;
                cbSrc += chromaGap;
            }
        }
    } else {
        // flexible YUV chroma to YV12 chroma
        ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YV12,
                "Unexpected preview format 0x%x", previewFormat);
        uint8_t *crDst = yDst;
        uint8_t *cbDst = yDst + chromaHeight * dstCStride;
        if (src.chromaStep == 1) {
            ALOGV("%s: Fast YV12->YV12", __FUNCTION__);
            // Source has planar chroma layout, can copy by row
            for (size_t row = 0; row < chromaHeight; row++) {
                memcpy(crDst, crSrc, chromaWidth);
                crDst += dstCStride;
                crSrc += src.chromaStride;
            }
            for (size_t row = 0; row < chromaHeight; row++) {
                memcpy(cbDst, cbSrc, chromaWidth);
                cbDst += dstCStride;
                cbSrc += src.chromaStride;
            }
        } else {
            ALOGV("%s: Generic->YV12", __FUNCTION__);
            // Generic copy, always works but not very efficient
            for (size_t row = 0; row < chromaHeight; row++) {
                for (size_t col = 0; col < chromaWidth; col++) {
                    *(crDst++) = *crSrc;
                    *(cbDst++) = *cbSrc;
                    crSrc += src.chromaStep;
                    cbSrc += src.chromaStep;
                }
                crSrc += chromaGap;
                cbSrc += chromaGap;
                crDst += dstChromaGap;
                cbDst += dstChromaGap;
            }
        }
    }

    return OK;
}

}; // namespace camera2
}; // namespace android
