/*
 * Copyright (C) 2009 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 "AVCDecoder"
#include <utils/Log.h>

#include "AVCDecoder.h"

#include "avcdec_api.h"
#include "avcdec_int.h"

#include <OMX_Component.h>

#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
#include <media/stagefright/foundation/hexdump.h>

namespace android {

static const char kStartCode[4] = { 0x00, 0x00, 0x00, 0x01 };

static int32_t Malloc(void *userData, int32_t size, int32_t attrs) {
    return reinterpret_cast<int32_t>(malloc(size));
}

static void Free(void *userData, int32_t ptr) {
    free(reinterpret_cast<void *>(ptr));
}

AVCDecoder::AVCDecoder(const sp<MediaSource> &source)
    : mSource(source),
      mStarted(false),
      mHandle(new tagAVCHandle),
      mInputBuffer(NULL),
      mAnchorTimeUs(0),
      mNumSamplesOutput(0),
      mPendingSeekTimeUs(-1),
      mPendingSeekMode(MediaSource::ReadOptions::SEEK_CLOSEST_SYNC),
      mTargetTimeUs(-1),
      mSPSSeen(false),
      mPPSSeen(false) {
    memset(mHandle, 0, sizeof(tagAVCHandle));
    mHandle->AVCObject = NULL;
    mHandle->userData = this;
    mHandle->CBAVC_DPBAlloc = ActivateSPSWrapper;
    mHandle->CBAVC_FrameBind = BindFrameWrapper;
    mHandle->CBAVC_FrameUnbind = UnbindFrame;
    mHandle->CBAVC_Malloc = Malloc;
    mHandle->CBAVC_Free = Free;

    mFormat = new MetaData;
    mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
    int32_t width, height;
    CHECK(mSource->getFormat()->findInt32(kKeyWidth, &width));
    CHECK(mSource->getFormat()->findInt32(kKeyHeight, &height));
    mFormat->setInt32(kKeyWidth, width);
    mFormat->setInt32(kKeyHeight, height);
    mFormat->setRect(kKeyCropRect, 0, 0, width - 1, height - 1);
    mFormat->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
    mFormat->setCString(kKeyDecoderComponent, "AVCDecoder");

    int64_t durationUs;
    if (mSource->getFormat()->findInt64(kKeyDuration, &durationUs)) {
        mFormat->setInt64(kKeyDuration, durationUs);
    }
}

AVCDecoder::~AVCDecoder() {
    if (mStarted) {
        stop();
    }

    PVAVCCleanUpDecoder(mHandle);

    delete mHandle;
    mHandle = NULL;
}

status_t AVCDecoder::start(MetaData *) {
    CHECK(!mStarted);

    uint32_t type;
    const void *data;
    size_t size;
    sp<MetaData> meta = mSource->getFormat();
    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
        // Parse the AVCDecoderConfigurationRecord

        const uint8_t *ptr = (const uint8_t *)data;

        CHECK(size >= 7);
        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
        uint8_t profile = ptr[1];
        uint8_t level = ptr[3];

        // There is decodable content out there that fails the following
        // assertion, let's be lenient for now...
        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved

        size_t lengthSize = 1 + (ptr[4] & 3);

        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
        // violates it...
        // CHECK((ptr[5] >> 5) == 7);  // reserved

        size_t numSeqParameterSets = ptr[5] & 31;

        ptr += 6;
        size -= 6;

        for (size_t i = 0; i < numSeqParameterSets; ++i) {
            CHECK(size >= 2);
            size_t length = U16_AT(ptr);

            ptr += 2;
            size -= 2;

            CHECK(size >= length);

            addCodecSpecificData(ptr, length);

            ptr += length;
            size -= length;
        }

        CHECK(size >= 1);
        size_t numPictureParameterSets = *ptr;
        ++ptr;
        --size;

        for (size_t i = 0; i < numPictureParameterSets; ++i) {
            CHECK(size >= 2);
            size_t length = U16_AT(ptr);

            ptr += 2;
            size -= 2;

            CHECK(size >= length);

            addCodecSpecificData(ptr, length);

            ptr += length;
            size -= length;
        }
    }

    mSource->start();

    mAnchorTimeUs = 0;
    mNumSamplesOutput = 0;
    mPendingSeekTimeUs = -1;
    mPendingSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
    mTargetTimeUs = -1;
    mSPSSeen = false;
    mPPSSeen = false;
    mStarted = true;

    return OK;
}

void AVCDecoder::addCodecSpecificData(const uint8_t *data, size_t size) {
    MediaBuffer *buffer = new MediaBuffer(size + 4);
    memcpy(buffer->data(), kStartCode, 4);
    memcpy((uint8_t *)buffer->data() + 4, data, size);
    buffer->set_range(0, size + 4);

    mCodecSpecificData.push(buffer);
}

status_t AVCDecoder::stop() {
    CHECK(mStarted);

    for (size_t i = 0; i < mCodecSpecificData.size(); ++i) {
        (*mCodecSpecificData.editItemAt(i)).release();
    }
    mCodecSpecificData.clear();

    if (mInputBuffer) {
        mInputBuffer->release();
        mInputBuffer = NULL;
    }

    mSource->stop();

    releaseFrames();

    mStarted = false;

    return OK;
}

sp<MetaData> AVCDecoder::getFormat() {
    return mFormat;
}

static void findNALFragment(
        const MediaBuffer *buffer, const uint8_t **fragPtr, size_t *fragSize) {
    const uint8_t *data =
        (const uint8_t *)buffer->data() + buffer->range_offset();

    size_t size = buffer->range_length();

    CHECK(size >= 4);
    CHECK(!memcmp(kStartCode, data, 4));

    size_t offset = 4;
    while (offset + 3 < size && memcmp(kStartCode, &data[offset], 4)) {
        ++offset;
    }

    *fragPtr = &data[4];
    if (offset + 3 >= size) {
        *fragSize = size - 4;
    } else {
        *fragSize = offset - 4;
    }
}

MediaBuffer *AVCDecoder::drainOutputBuffer() {
    int32_t index;
    int32_t Release;
    AVCFrameIO Output;
    Output.YCbCr[0] = Output.YCbCr[1] = Output.YCbCr[2] = NULL;
    AVCDec_Status status = PVAVCDecGetOutput(mHandle, &index, &Release, &Output);

    if (status != AVCDEC_SUCCESS) {
        LOGV("PVAVCDecGetOutput returned error %d", status);
        return NULL;
    }

    CHECK(index >= 0);
    CHECK(index < (int32_t)mFrames.size());

    MediaBuffer *mbuf = mFrames.editItemAt(index);

    bool skipFrame = false;

    if (mTargetTimeUs >= 0) {
        int64_t timeUs;
        CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
        CHECK(timeUs <= mTargetTimeUs);

        if (timeUs < mTargetTimeUs) {
            // We're still waiting for the frame with the matching
            // timestamp and we won't return the current one.
            skipFrame = true;

            LOGV("skipping frame at %lld us", timeUs);
        } else {
            LOGV("found target frame at %lld us", timeUs);

            mTargetTimeUs = -1;
        }
    }

    if (!skipFrame) {
        mbuf->set_range(0, mbuf->size());
        mbuf->add_ref();

        return mbuf;
    }

    return new MediaBuffer(0);
}

status_t AVCDecoder::read(
        MediaBuffer **out, const ReadOptions *options) {
    *out = NULL;

    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
        LOGV("seek requested to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);

        CHECK(seekTimeUs >= 0);
        mPendingSeekTimeUs = seekTimeUs;
        mPendingSeekMode = mode;

        if (mInputBuffer) {
            mInputBuffer->release();
            mInputBuffer = NULL;
        }

        PVAVCDecReset(mHandle);
    }

    if (mInputBuffer == NULL) {
        LOGV("fetching new input buffer.");

        bool seeking = false;

        if (!mCodecSpecificData.isEmpty()) {
            mInputBuffer = mCodecSpecificData.editItemAt(0);
            mCodecSpecificData.removeAt(0);
        } else {
            for (;;) {
                if (mPendingSeekTimeUs >= 0) {
                    LOGV("reading data from timestamp %lld (%.2f secs)",
                         mPendingSeekTimeUs, mPendingSeekTimeUs / 1E6);
                }

                ReadOptions seekOptions;
                if (mPendingSeekTimeUs >= 0) {
                    seeking = true;

                    seekOptions.setSeekTo(mPendingSeekTimeUs, mPendingSeekMode);
                    mPendingSeekTimeUs = -1;
                }
                status_t err = mSource->read(&mInputBuffer, &seekOptions);
                seekOptions.clearSeekTo();

                if (err != OK) {
                    *out = drainOutputBuffer();
                    return (*out == NULL)  ? err : (status_t)OK;
                }

                if (mInputBuffer->range_length() > 0) {
                    break;
                }

                mInputBuffer->release();
                mInputBuffer = NULL;
            }
        }

        if (seeking) {
            int64_t targetTimeUs;
            if (mInputBuffer->meta_data()->findInt64(kKeyTargetTime, &targetTimeUs)
                    && targetTimeUs >= 0) {
                mTargetTimeUs = targetTimeUs;
            } else {
                mTargetTimeUs = -1;
            }
        }
    }

    const uint8_t *fragPtr;
    size_t fragSize;
    findNALFragment(mInputBuffer, &fragPtr, &fragSize);

    bool releaseFragment = true;
    status_t err = UNKNOWN_ERROR;

    int nalType;
    int nalRefIdc;
    AVCDec_Status res =
        PVAVCDecGetNALType(
                const_cast<uint8_t *>(fragPtr), fragSize,
                &nalType, &nalRefIdc);

    if (res != AVCDEC_SUCCESS) {
        LOGV("cannot determine nal type");
    } else if (nalType == AVC_NALTYPE_SPS || nalType == AVC_NALTYPE_PPS
                || (mSPSSeen && mPPSSeen)) {
        switch (nalType) {
            case AVC_NALTYPE_SPS:
            {
                mSPSSeen = true;

                res = PVAVCDecSeqParamSet(
                        mHandle, const_cast<uint8_t *>(fragPtr),
                        fragSize);

                if (res != AVCDEC_SUCCESS) {
                    LOGV("PVAVCDecSeqParamSet returned error %d", res);
                    break;
                }

                AVCDecObject *pDecVid = (AVCDecObject *)mHandle->AVCObject;

                int32_t width =
                    (pDecVid->seqParams[0]->pic_width_in_mbs_minus1 + 1) * 16;

                int32_t height =
                    (pDecVid->seqParams[0]->pic_height_in_map_units_minus1 + 1) * 16;

                int32_t crop_left, crop_right, crop_top, crop_bottom;
                if (pDecVid->seqParams[0]->frame_cropping_flag)
                {
                    crop_left = 2 * pDecVid->seqParams[0]->frame_crop_left_offset;
                    crop_right =
                        width - (2 * pDecVid->seqParams[0]->frame_crop_right_offset + 1);

                    if (pDecVid->seqParams[0]->frame_mbs_only_flag)
                    {
                        crop_top = 2 * pDecVid->seqParams[0]->frame_crop_top_offset;
                        crop_bottom =
                            height -
                            (2 * pDecVid->seqParams[0]->frame_crop_bottom_offset + 1);
                    }
                    else
                    {
                        crop_top = 4 * pDecVid->seqParams[0]->frame_crop_top_offset;
                        crop_bottom =
                            height -
                            (4 * pDecVid->seqParams[0]->frame_crop_bottom_offset + 1);
                    }
                } else {
                    crop_bottom = height - 1;
                    crop_right = width - 1;
                    crop_top = crop_left = 0;
                }

                int32_t prevCropLeft, prevCropTop;
                int32_t prevCropRight, prevCropBottom;
                if (!mFormat->findRect(
                            kKeyCropRect,
                            &prevCropLeft, &prevCropTop,
                            &prevCropRight, &prevCropBottom)) {
                    prevCropLeft = prevCropTop = 0;
                    prevCropRight = width - 1;
                    prevCropBottom = height - 1;
                }

                int32_t oldWidth, oldHeight;
                CHECK(mFormat->findInt32(kKeyWidth, &oldWidth));
                CHECK(mFormat->findInt32(kKeyHeight, &oldHeight));

                if (oldWidth != width || oldHeight != height
                        || prevCropLeft != crop_left
                        || prevCropTop != crop_top
                        || prevCropRight != crop_right
                        || prevCropBottom != crop_bottom) {
                    mFormat->setRect(
                            kKeyCropRect,
                            crop_left, crop_top, crop_right, crop_bottom);

                    mFormat->setInt32(kKeyWidth, width);
                    mFormat->setInt32(kKeyHeight, height);

                    err = INFO_FORMAT_CHANGED;
                } else {
                    *out = new MediaBuffer(0);
                    err = OK;
                }
                break;
            }

            case AVC_NALTYPE_PPS:
            {
                mPPSSeen = true;

                res = PVAVCDecPicParamSet(
                        mHandle, const_cast<uint8_t *>(fragPtr),
                        fragSize);

                if (res != AVCDEC_SUCCESS) {
                    LOGV("PVAVCDecPicParamSet returned error %d", res);
                    break;
                }

                *out = new MediaBuffer(0);

                err = OK;
                break;
            }

            case AVC_NALTYPE_SLICE:
            case AVC_NALTYPE_IDR:
            {
                res = PVAVCDecodeSlice(
                        mHandle, const_cast<uint8_t *>(fragPtr),
                        fragSize);

                if (res == AVCDEC_PICTURE_OUTPUT_READY) {
                    MediaBuffer *mbuf = drainOutputBuffer();
                    if (mbuf == NULL) {
                        break;
                    }

                    *out = mbuf;

                    // Do _not_ release input buffer yet.

                    releaseFragment = false;
                    err = OK;
                    break;
                }

                if (res == AVCDEC_PICTURE_READY || res == AVCDEC_SUCCESS) {
                    *out = new MediaBuffer(0);

                    err = OK;
                } else {
                    LOGV("PVAVCDecodeSlice returned error %d", res);
                }
                break;
            }

            case AVC_NALTYPE_SEI:
            {
                res = PVAVCDecSEI(
                        mHandle, const_cast<uint8_t *>(fragPtr),
                        fragSize);

                if (res != AVCDEC_SUCCESS) {
                    break;
                }

                *out = new MediaBuffer(0);

                err = OK;
                break;
            }

            case AVC_NALTYPE_AUD:
            case AVC_NALTYPE_FILL:
            case AVC_NALTYPE_EOSEQ:
            {
                *out = new MediaBuffer(0);

                err = OK;
                break;
            }

            default:
            {
                LOGE("Should not be here, unknown nalType %d", nalType);
                CHECK(!"Should not be here");
                break;
            }
        }
    } else {
        // We haven't seen SPS or PPS yet.

        *out = new MediaBuffer(0);
        err = OK;
    }

    if (releaseFragment) {
        size_t offset = mInputBuffer->range_offset();
        if (fragSize + 4 == mInputBuffer->range_length()) {
            mInputBuffer->release();
            mInputBuffer = NULL;
        } else {
            mInputBuffer->set_range(
                    offset + fragSize + 4,
                    mInputBuffer->range_length() - fragSize - 4);
        }
    }

    return err;
}

// static
int32_t AVCDecoder::ActivateSPSWrapper(
        void *userData, unsigned int sizeInMbs, unsigned int numBuffers) {
    return static_cast<AVCDecoder *>(userData)->activateSPS(sizeInMbs, numBuffers);
}

// static
int32_t AVCDecoder::BindFrameWrapper(
        void *userData, int32_t index, uint8_t **yuv) {
    return static_cast<AVCDecoder *>(userData)->bindFrame(index, yuv);
}

// static
void AVCDecoder::UnbindFrame(void *userData, int32_t index) {
}

int32_t AVCDecoder::activateSPS(
        unsigned int sizeInMbs, unsigned int numBuffers) {
    CHECK(mFrames.isEmpty());

    size_t frameSize = (sizeInMbs << 7) * 3;
    for (unsigned int i = 0; i < numBuffers; ++i) {
        MediaBuffer *buffer = new MediaBuffer(frameSize);
        buffer->setObserver(this);

        mFrames.push(buffer);
    }

    return 1;
}

int32_t AVCDecoder::bindFrame(int32_t index, uint8_t **yuv) {
    CHECK(index >= 0);
    CHECK(index < (int32_t)mFrames.size());

    CHECK(mInputBuffer != NULL);
    int64_t timeUs;
    CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
    mFrames[index]->meta_data()->setInt64(kKeyTime, timeUs);

    *yuv = (uint8_t *)mFrames[index]->data();

    return 1;
}

void AVCDecoder::releaseFrames() {
    for (size_t i = 0; i < mFrames.size(); ++i) {
        MediaBuffer *buffer = mFrames.editItemAt(i);

        buffer->setObserver(NULL);
        buffer->release();
    }
    mFrames.clear();
}

void AVCDecoder::signalBufferReturned(MediaBuffer *buffer) {
}

}  // namespace android
