/*
 * Copyright (C) 2011 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_NDEBUG 0
#define LOG_TAG "SoftAVC"
#include <utils/Log.h>

#include "SoftAVC.h"

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/IOMX.h>


namespace android {

static const CodecProfileLevel kProfileLevels[] = {
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1  },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11 },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12 },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13 },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2  },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21 },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22 },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3  },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31 },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4  },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42 },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel5  },
    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel51 },
};

SoftAVC::SoftAVC(
        const char *name,
        const OMX_CALLBACKTYPE *callbacks,
        OMX_PTR appData,
        OMX_COMPONENTTYPE **component)
    : SoftVideoDecoderOMXComponent(
            name, "video_decoder.avc", OMX_VIDEO_CodingAVC,
            kProfileLevels, ARRAY_SIZE(kProfileLevels),
            320 /* width */, 240 /* height */, callbacks, appData, component),
      mHandle(NULL),
      mInputBufferCount(0),
      mFirstPicture(NULL),
      mFirstPictureId(-1),
      mPicId(0),
      mHeadersDecoded(false),
      mEOSStatus(INPUT_DATA_AVAILABLE),
      mSignalledError(false) {
    const size_t kMinCompressionRatio = 2;
    const size_t kMaxOutputBufferSize = 2048 * 2048 * 3 / 2;
    initPorts(
            kNumInputBuffers, kMaxOutputBufferSize / kMinCompressionRatio /* minInputBufferSize */,
            kNumOutputBuffers, MEDIA_MIMETYPE_VIDEO_AVC, kMinCompressionRatio);

    CHECK_EQ(initDecoder(), (status_t)OK);
}

SoftAVC::~SoftAVC() {
    H264SwDecRelease(mHandle);
    mHandle = NULL;

    while (mPicToHeaderMap.size() != 0) {
        OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.editValueAt(0);
        mPicToHeaderMap.removeItemsAt(0);
        delete header;
        header = NULL;
    }
    List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
    List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
    CHECK(outQueue.empty());
    CHECK(inQueue.empty());

    delete[] mFirstPicture;
}

status_t SoftAVC::initDecoder() {
    // Force decoder to output buffers in display order.
    if (H264SwDecInit(&mHandle, 0) == H264SWDEC_OK) {
        return OK;
    }
    return UNKNOWN_ERROR;
}

void SoftAVC::onQueueFilled(OMX_U32 /* portIndex */) {
    if (mSignalledError || mOutputPortSettingsChange != NONE) {
        return;
    }

    if (mEOSStatus == OUTPUT_FRAMES_FLUSHED) {
        return;
    }

    List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
    List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);

    if (mHeadersDecoded) {
        // Dequeue any already decoded output frames to free up space
        // in the output queue.

        drainAllOutputBuffers(false /* eos */);
    }

    H264SwDecRet ret = H264SWDEC_PIC_RDY;
    bool portWillReset = false;
    while ((mEOSStatus != INPUT_DATA_AVAILABLE || !inQueue.empty())
            && outQueue.size() == kNumOutputBuffers) {

        if (mEOSStatus == INPUT_EOS_SEEN) {
            drainAllOutputBuffers(true /* eos */);
            return;
        }

        BufferInfo *inInfo = *inQueue.begin();
        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
        ++mPicId;

        OMX_BUFFERHEADERTYPE *header = new OMX_BUFFERHEADERTYPE;
        memset(header, 0, sizeof(OMX_BUFFERHEADERTYPE));
        header->nTimeStamp = inHeader->nTimeStamp;
        header->nFlags = inHeader->nFlags;
        if (header->nFlags & OMX_BUFFERFLAG_EOS) {
            mEOSStatus = INPUT_EOS_SEEN;
        }
        mPicToHeaderMap.add(mPicId, header);
        inQueue.erase(inQueue.begin());

        H264SwDecInput inPicture;
        H264SwDecOutput outPicture;
        memset(&inPicture, 0, sizeof(inPicture));
        inPicture.dataLen = inHeader->nFilledLen;
        inPicture.pStream = inHeader->pBuffer + inHeader->nOffset;
        inPicture.picId = mPicId;
        inPicture.intraConcealmentMethod = 1;
        H264SwDecPicture decodedPicture;

        while (inPicture.dataLen > 0) {
            ret = H264SwDecDecode(mHandle, &inPicture, &outPicture);
            if (ret == H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY ||
                ret == H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY) {
                inPicture.dataLen -= (u32)(outPicture.pStrmCurrPos - inPicture.pStream);
                inPicture.pStream = outPicture.pStrmCurrPos;
                if (ret == H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY) {
                    mHeadersDecoded = true;
                    H264SwDecInfo decoderInfo;
                    CHECK(H264SwDecGetInfo(mHandle, &decoderInfo) == H264SWDEC_OK);

                    SoftVideoDecoderOMXComponent::CropSettingsMode cropSettingsMode =
                        handleCropParams(decoderInfo);
                    handlePortSettingsChange(
                            &portWillReset, decoderInfo.picWidth, decoderInfo.picHeight,
                            cropSettingsMode);
                }
            } else {
                if (portWillReset) {
                    if (H264SwDecNextPicture(mHandle, &decodedPicture, 0)
                        == H264SWDEC_PIC_RDY) {

                        // Save this output buffer; otherwise, it will be
                        // lost during dynamic port reconfiguration because
                        // OpenMAX client will delete _all_ output buffers
                        // in the process.
                        saveFirstOutputBuffer(
                            decodedPicture.picId,
                            (uint8_t *)decodedPicture.pOutputPicture);
                    }
                }
                inPicture.dataLen = 0;
                if (ret < 0) {
                    ALOGE("Decoder failed: %d", ret);

                    notify(OMX_EventError, OMX_ErrorUndefined,
                           ERROR_MALFORMED, NULL);

                    mSignalledError = true;
                    return;
                }
            }
        }
        inInfo->mOwnedByUs = false;
        notifyEmptyBufferDone(inHeader);

        if (portWillReset) {
            return;
        }

        if (mFirstPicture && !outQueue.empty()) {
            if (!drainOneOutputBuffer(mFirstPictureId, mFirstPicture)) {
                ALOGE("Drain failed");
                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
                mSignalledError = true;
                return;
            }
            delete[] mFirstPicture;
            mFirstPicture = NULL;
            mFirstPictureId = -1;
        }

        drainAllOutputBuffers(false /* eos */);
    }
}

SoftVideoDecoderOMXComponent::CropSettingsMode SoftAVC::handleCropParams(
        const H264SwDecInfo& decInfo) {
    if (!decInfo.croppingFlag) {
        return kCropUnSet;
    }

    const CropParams& crop = decInfo.cropParams;
    if (mCropLeft == crop.cropLeftOffset &&
        mCropTop == crop.cropTopOffset &&
        mCropWidth == crop.cropOutWidth &&
        mCropHeight == crop.cropOutHeight) {
        return kCropSet;
    }

    mCropLeft = crop.cropLeftOffset;
    mCropTop = crop.cropTopOffset;
    mCropWidth = crop.cropOutWidth;
    mCropHeight = crop.cropOutHeight;
    return kCropChanged;
}

void SoftAVC::saveFirstOutputBuffer(int32_t picId, uint8_t *data) {
    CHECK(mFirstPicture == NULL);
    mFirstPictureId = picId;

    uint32_t pictureSize = mWidth * mHeight * 3 / 2;
    mFirstPicture = new uint8_t[pictureSize];
    memcpy(mFirstPicture, data, pictureSize);
}

bool SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) {
    List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
    BufferInfo *outInfo = *outQueue.begin();
    OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
    OMX_U32 frameSize = mWidth * mHeight * 3 / 2;
    if (outHeader->nAllocLen - outHeader->nOffset < frameSize) {
        android_errorWriteLog(0x534e4554, "27833616");
        return false;
    }
    outQueue.erase(outQueue.begin());
    OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.valueFor(picId);
    outHeader->nTimeStamp = header->nTimeStamp;
    outHeader->nFlags = header->nFlags;
    outHeader->nFilledLen = frameSize;

    uint8_t *dst = outHeader->pBuffer + outHeader->nOffset;
    const uint8_t *srcY = data;
    const uint8_t *srcU = srcY + mWidth * mHeight;
    const uint8_t *srcV = srcU + mWidth * mHeight / 4;
    size_t srcYStride = mWidth;
    size_t srcUStride = mWidth / 2;
    size_t srcVStride = srcUStride;
    copyYV12FrameToOutputBuffer(dst, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride);

    mPicToHeaderMap.removeItem(picId);
    delete header;
    outInfo->mOwnedByUs = false;
    notifyFillBufferDone(outHeader);
    return true;
}

void SoftAVC::drainAllOutputBuffers(bool eos) {
    List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
    H264SwDecPicture decodedPicture;

    if (mHeadersDecoded) {
        while (!outQueue.empty()
                && H264SWDEC_PIC_RDY == H264SwDecNextPicture(
                    mHandle, &decodedPicture, eos /* flush */)) {
            int32_t picId = decodedPicture.picId;
            uint8_t *data = (uint8_t *) decodedPicture.pOutputPicture;
            if (!drainOneOutputBuffer(picId, data)) {
                ALOGE("Drain failed");
                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
                mSignalledError = true;
                return;
            }
        }
    }

    if (!eos) {
        return;
    }

    while (!outQueue.empty()) {
        BufferInfo *outInfo = *outQueue.begin();
        outQueue.erase(outQueue.begin());
        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;

        outHeader->nTimeStamp = 0;
        outHeader->nFilledLen = 0;
        outHeader->nFlags = OMX_BUFFERFLAG_EOS;

        outInfo->mOwnedByUs = false;
        notifyFillBufferDone(outHeader);

        mEOSStatus = OUTPUT_FRAMES_FLUSHED;
    }
}

void SoftAVC::onPortFlushCompleted(OMX_U32 portIndex) {
    if (portIndex == kInputPortIndex) {
        mEOSStatus = INPUT_DATA_AVAILABLE;
    }
}

void SoftAVC::onReset() {
    SoftVideoDecoderOMXComponent::onReset();
    mSignalledError = false;
}

}  // namespace android

android::SoftOMXComponent *createSoftOMXComponent(
        const char *name, const OMX_CALLBACKTYPE *callbacks,
        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
    return new android::SoftAVC(name, callbacks, appData, component);
}
