/*
* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
*
* 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.
*/

#include "VideoDecoderBase.h"
#include "VideoDecoderTrace.h"
#include <string.h>
#include <va/va_android.h>
#include <va/va_tpi.h>
#ifdef  __SSE4_1__
#include "use_util_sse4.h"
#endif

#define INVALID_PTS ((uint64_t)-1)
#define MAXIMUM_POC  0x7FFFFFFF
#define MINIMUM_POC  0x80000000
#define ANDROID_DISPLAY_HANDLE 0x18C34078

VideoDecoderBase::VideoDecoderBase(const char *mimeType, _vbp_parser_type type)
    : mInitialized(false),
      mLowDelay(false),
      mStoreMetaData(false),
      mDisplay(NULL),
      mVADisplay(NULL),
      mVAContext(VA_INVALID_ID),
      mVAConfig(VA_INVALID_ID),
      mVAStarted(false),
      mCurrentPTS(INVALID_PTS),
      mAcquiredBuffer(NULL),
      mLastReference(NULL),
      mForwardReference(NULL),
      mDecodingFrame(false),
      mSizeChanged(false),
      mShowFrame(true),
      mOutputWindowSize(OUTPUT_WINDOW_SIZE),
      mRotationDegrees(0),
      mErrReportEnabled(false),
      mWiDiOn(false),
      mRawOutput(false),
      mManageReference(true),
      mOutputMethod(OUTPUT_BY_PCT),
      mNumSurfaces(0),
      mSurfaceBuffers(NULL),
      mOutputHead(NULL),
      mOutputTail(NULL),
      mSurfaces(NULL),
      mVASurfaceAttrib(NULL),
      mSurfaceUserPtr(NULL),
      mSurfaceAcquirePos(0),
      mNextOutputPOC(MINIMUM_POC),
      mParserType(type),
      mParserHandle(NULL),
      mSignalBufferSize(0) {

    memset(&mVideoFormatInfo, 0, sizeof(VideoFormatInfo));
    memset(&mConfigBuffer, 0, sizeof(mConfigBuffer));
    for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
         mSignalBufferPre[i] = NULL;
    }
    pthread_mutex_init(&mLock, NULL);
    pthread_mutex_init(&mFormatLock, NULL);
    mVideoFormatInfo.mimeType = strdup(mimeType);
    mUseGEN = false;
    mMetaDataBuffersNum = 0;
    mLibHandle = NULL;
    mParserOpen = NULL;
    mParserClose = NULL;
    mParserParse = NULL;
    mParserQuery = NULL;
    mParserFlush = NULL;
    mParserUpdate = NULL;
}

VideoDecoderBase::~VideoDecoderBase() {
    pthread_mutex_destroy(&mLock);
    pthread_mutex_destroy(&mFormatLock);
    stop();
    free(mVideoFormatInfo.mimeType);
}

Decode_Status VideoDecoderBase::start(VideoConfigBuffer *buffer) {
    if (buffer == NULL) {
        return DECODE_INVALID_DATA;
    }

    if (mParserHandle != NULL) {
        WTRACE("Decoder has already started.");
        return DECODE_SUCCESS;
    }
    mLibHandle = dlopen("libmixvbp.so", RTLD_NOW);
    if (mLibHandle == NULL) {
       return DECODE_NO_PARSER;
    }
    mParserOpen = (OpenFunc)dlsym(mLibHandle, "vbp_open");
    mParserClose = (CloseFunc)dlsym(mLibHandle, "vbp_close");
    mParserParse = (ParseFunc)dlsym(mLibHandle, "vbp_parse");
    mParserQuery = (QueryFunc)dlsym(mLibHandle, "vbp_query");
    mParserFlush = (FlushFunc)dlsym(mLibHandle, "vbp_flush");
    if (mParserOpen == NULL || mParserClose == NULL || mParserParse == NULL
        || mParserQuery == NULL || mParserFlush == NULL) {
        return DECODE_NO_PARSER;
    }
#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
    mParserUpdate = (UpdateFunc)dlsym(mLibHandle, "vbp_update");
    if (mParserUpdate == NULL) {
        return DECODE_NO_PARSER;
    }
#endif
    if ((int32_t)mParserType != VBP_INVALID) {
        ITRACE("mParserType = %d", mParserType);
        if (mParserOpen(mParserType, &mParserHandle) != VBP_OK) {
            ETRACE("Failed to open VBP parser.");
            return DECODE_NO_PARSER;
        }
    }
    // keep a copy of configure buffer, meta data only. It can be used to override VA setup parameter.
    mConfigBuffer = *buffer;
    mConfigBuffer.data = NULL;
    mConfigBuffer.size = 0;

    mVideoFormatInfo.width = buffer->width;
    mVideoFormatInfo.height = buffer->height;
    if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) {
        mVideoFormatInfo.surfaceWidth = buffer->graphicBufferWidth;
        mVideoFormatInfo.surfaceHeight = buffer->graphicBufferHeight;
    }
    mLowDelay = buffer->flag & WANT_LOW_DELAY;
    mStoreMetaData = buffer->flag & WANT_STORE_META_DATA;
    mRawOutput = buffer->flag & WANT_RAW_OUTPUT;
    if (mRawOutput) {
        WTRACE("Output is raw data.");
    }

    return DECODE_SUCCESS;
}


Decode_Status VideoDecoderBase::reset(VideoConfigBuffer *buffer) {
    if (buffer == NULL) {
        return DECODE_INVALID_DATA;
    }

    // if VA is already started, terminate VA as graphic buffers are reallocated by omxcodec
    terminateVA();

    // reset the mconfigBuffer to pass it for startVA.
    mConfigBuffer = *buffer;
    mConfigBuffer.data = NULL;
    mConfigBuffer.size = 0;

    mVideoFormatInfo.width = buffer->width;
    mVideoFormatInfo.height = buffer->height;
    if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) {
        mVideoFormatInfo.surfaceWidth = buffer->graphicBufferWidth;
        mVideoFormatInfo.surfaceHeight = buffer->graphicBufferHeight;
    }
    mVideoFormatInfo.actualBufferNeeded = mConfigBuffer.surfaceNumber;
    mLowDelay = buffer->flag & WANT_LOW_DELAY;
    mStoreMetaData = buffer->flag & WANT_STORE_META_DATA;
    mMetaDataBuffersNum = 0;
    mRawOutput = buffer->flag & WANT_RAW_OUTPUT;
    if (mRawOutput) {
        WTRACE("Output is raw data.");
    }
    return DECODE_SUCCESS;
}



void VideoDecoderBase::stop(void) {
    terminateVA();

    mCurrentPTS = INVALID_PTS;
    mAcquiredBuffer = NULL;
    mLastReference = NULL;
    mForwardReference = NULL;
    mDecodingFrame = false;
    mSizeChanged = false;

    // private variables
    mLowDelay = false;
    mStoreMetaData = false;
    mRawOutput = false;
    mNumSurfaces = 0;
    mSurfaceAcquirePos = 0;
    mNextOutputPOC = MINIMUM_POC;
    mVideoFormatInfo.valid = false;
    if (mParserHandle){
        mParserClose(mParserHandle);
        mParserHandle = NULL;
    }
    if (mLibHandle) {
        dlclose(mLibHandle);
        mLibHandle = NULL;
    }
}

void VideoDecoderBase::flush(void) {
    if (mVAStarted == false) {
        // nothing to flush at this stage
        return;
    }

    endDecodingFrame(true);

    VideoSurfaceBuffer *p = mOutputHead;
    // check if there's buffer with DRC flag in the output queue
    while (p) {
        if (p->renderBuffer.flag & IS_RESOLUTION_CHANGE) {
            mSizeChanged = true;
            break;
        }
        p = p->next;
    }
    // avoid setting mSurfaceAcquirePos  to 0 as it may cause tearing
    // (surface is still being rendered)
    mSurfaceAcquirePos = (mSurfaceAcquirePos  + 1) % mNumSurfaces;
    mNextOutputPOC = MINIMUM_POC;
    mCurrentPTS = INVALID_PTS;
    mAcquiredBuffer = NULL;
    mLastReference = NULL;
    mForwardReference = NULL;
    mOutputHead = NULL;
    mOutputTail = NULL;
    mDecodingFrame = false;

    // flush vbp parser
    if (mParserHandle && (mParserFlush(mParserHandle) != VBP_OK)) {
        WTRACE("Failed to flush parser. Continue");
    }

    // initialize surface buffer without resetting mapped/raw data
    initSurfaceBuffer(false);

}

void VideoDecoderBase::freeSurfaceBuffers(void) {
    if (mVAStarted == false) {
        // nothing to free surface buffers at this stage
        return;
    }

    pthread_mutex_lock(&mLock);

    endDecodingFrame(true);

    // if VA is already started, terminate VA as graphic buffers are reallocated by omxcodec
    terminateVA();

    pthread_mutex_unlock(&mLock);
}

const VideoFormatInfo* VideoDecoderBase::getFormatInfo(void) {
    if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) && mStoreMetaData) {
        // Do nothing here, just to avoid thread
        // contention in updateFormatInfo()
        pthread_mutex_lock(&mFormatLock);
        pthread_mutex_unlock(&mFormatLock);
    }

    return &mVideoFormatInfo;
}

int VideoDecoderBase::getOutputQueueLength(void) {
    VideoSurfaceBuffer *p = mOutputHead;

    int i = 0;
    while (p) {
        p = p->next;
        i++;
    }

    return i;
}

const VideoRenderBuffer* VideoDecoderBase::getOutput(bool draining, VideoErrorBuffer *outErrBuf) {
    if (mVAStarted == false) {
        return NULL;
    }
    bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;

    if (draining) {
        // complete decoding the last frame and ignore return
        endDecodingFrame(false);
    }

    if (mOutputHead == NULL) {
        return NULL;
    }

    // output by position (the first buffer)
    VideoSurfaceBuffer *outputByPos = mOutputHead;

    if (mLowDelay) {
        mOutputHead = mOutputHead->next;
        if (mOutputHead == NULL) {
            mOutputTail = NULL;
        }
        vaSetTimestampForSurface(mVADisplay, outputByPos->renderBuffer.surface, outputByPos->renderBuffer.timeStamp);
        if (useGraphicBuffer && !mUseGEN) {
            vaSyncSurface(mVADisplay, outputByPos->renderBuffer.surface);
            fillDecodingErrors(&(outputByPos->renderBuffer));
        }
        if (draining && mOutputTail == NULL) {
            outputByPos->renderBuffer.flag |= IS_EOS;
        }
        drainDecodingErrors(outErrBuf, &(outputByPos->renderBuffer));

        return &(outputByPos->renderBuffer);
    }

    VideoSurfaceBuffer *output = NULL;
    if (mOutputMethod == OUTPUT_BY_POC) {
        output = findOutputByPoc(draining);
    } else if (mOutputMethod == OUTPUT_BY_PCT) {
        output = findOutputByPct(draining);
    } else {
        ETRACE("Invalid output method.");
        return NULL;
    }

    if (output == NULL) {
        return NULL;
    }

    if (output != outputByPos) {
        // remove this output from middle or end of the list
        VideoSurfaceBuffer *p = outputByPos;
        while (p->next != output) {
            p = p->next;
        }
        p->next = output->next;
        if (mOutputTail == output) {
            mOutputTail = p;
        }
    } else {
        // remove this output from head of the list
        mOutputHead = mOutputHead->next;
        if (mOutputHead == NULL) {
            mOutputTail = NULL;
        }
    }
    //VTRACE("Output POC %d for display (pts = %.2f)", output->pictureOrder, output->renderBuffer.timeStamp/1E6);
    vaSetTimestampForSurface(mVADisplay, output->renderBuffer.surface, output->renderBuffer.timeStamp);

    if (useGraphicBuffer && !mUseGEN) {
        vaSyncSurface(mVADisplay, output->renderBuffer.surface);
        fillDecodingErrors(&(output->renderBuffer));
    }

    if (draining && mOutputTail == NULL) {
        output->renderBuffer.flag |= IS_EOS;
    }

    drainDecodingErrors(outErrBuf, &(output->renderBuffer));

    return &(output->renderBuffer);
}

VideoSurfaceBuffer* VideoDecoderBase::findOutputByPts() {
    // output by presentation time stamp - buffer with the smallest time stamp is output
    VideoSurfaceBuffer *p = mOutputHead;
    VideoSurfaceBuffer *outputByPts = NULL;
    uint64_t pts = INVALID_PTS;
    do {
        if ((uint64_t)(p->renderBuffer.timeStamp) <= pts) {
            // find buffer with the smallest PTS
            pts = p->renderBuffer.timeStamp;
            outputByPts = p;
        }
        p = p->next;
    } while (p != NULL);

    return outputByPts;
}

VideoSurfaceBuffer* VideoDecoderBase::findOutputByPct(bool draining) {
    // output by picture coding type (PCT)
    // if there is more than one reference frame, the first reference frame is ouput, otherwise,
    // output non-reference frame if there is any.

    VideoSurfaceBuffer *p = mOutputHead;
    VideoSurfaceBuffer *outputByPct = NULL;
    int32_t reference = 0;
    do {
        if (p->referenceFrame) {
            reference++;
            if (reference > 1) {
                // mOutputHead must be a reference frame
                outputByPct = mOutputHead;
                break;
            }
        } else {
            // first non-reference frame
            outputByPct = p;
            break;
        }
        p = p->next;
    } while (p != NULL);

    if (outputByPct == NULL && draining) {
        outputByPct = mOutputHead;
    }
    return  outputByPct;
}

#if 0
VideoSurfaceBuffer* VideoDecoderBase::findOutputByPoc(bool draining) {
    // output by picture order count (POC)
    // Output criteria:
    // if there is IDR frame (POC == 0), all the frames before IDR must be output;
    // Otherwise, if draining flag is set or list is full, frame with the least POC is output;
    // Otherwise, NOTHING is output

    int32_t dpbFullness = 0;
    for (int32_t i = 0; i < mNumSurfaces; i++) {
        // count num of reference frames
        if (mSurfaceBuffers[i].asReferernce) {
            dpbFullness++;
        }
    }

    if (mAcquiredBuffer && mAcquiredBuffer->asReferernce) {
        // frame is being decoded and is not ready for output yet
        dpbFullness--;
    }

    VideoSurfaceBuffer *p = mOutputHead;
    while (p != NULL) {
        // count dpbFullness with non-reference frame in the output queue
        if (p->asReferernce == false) {
            dpbFullness++;
        }
        p = p->next;
    }

Retry:
    p = mOutputHead;
    VideoSurfaceBuffer *outputByPoc = NULL;
    int32_t count = 0;
    int32_t poc = MAXIMUM_POC;

    do {
        if (p->pictureOrder == 0) {
            // output picture with the least POC before IDR
            if (outputByPoc != NULL) {
                mNextOutputPOC = outputByPoc->pictureOrder + 1;
                return outputByPoc;
            } else {
                mNextOutputPOC = MINIMUM_POC;
            }
        }

        // POC of  the output candidate must not be less than mNextOutputPOC
        if (p->pictureOrder < mNextOutputPOC) {
            break;
        }

        if (p->pictureOrder < poc) {
            // update the least POC.
            poc = p->pictureOrder;
            outputByPoc = p;
        }
        count++;
        p = p->next;
    } while (p != NULL && count < mOutputWindowSize);

    if (draining == false && dpbFullness < mOutputWindowSize) {
        // list is not  full and we are not  in draining state
        // if DPB is already full, one frame must be output
        return NULL;
    }

    if (outputByPoc == NULL) {
        mNextOutputPOC = MINIMUM_POC;
        goto Retry;
    }

    // for debugging purpose
    if (outputByPoc->pictureOrder != 0 && outputByPoc->pictureOrder < mNextOutputPOC) {
        ETRACE("Output POC is not incremental, expected %d, actual %d", mNextOutputPOC, outputByPoc->pictureOrder);
        //gaps_in_frame_num_value_allowed_flag is not currently supported
    }

    mNextOutputPOC = outputByPoc->pictureOrder + 1;

    return outputByPoc;
}
#else
VideoSurfaceBuffer* VideoDecoderBase::findOutputByPoc(bool draining) {
    VideoSurfaceBuffer *output = NULL;
    VideoSurfaceBuffer *p = mOutputHead;
    int32_t count = 0;
    int32_t poc = MAXIMUM_POC;
    VideoSurfaceBuffer *outputleastpoc = mOutputHead;
    do {
        count++;
        if (p->pictureOrder == 0) {
            // any picture before this POC (new IDR) must be output
            if (output == NULL) {
                mNextOutputPOC = MINIMUM_POC;
                // looking for any POC with negative value
            } else {
                mNextOutputPOC = output->pictureOrder + 1;
                break;
            }
        }
        if (p->pictureOrder < poc && p->pictureOrder >= mNextOutputPOC) {
            // this POC meets ouput criteria.
            poc = p->pictureOrder;
            output = p;
            outputleastpoc = p;
        }
        if (poc == mNextOutputPOC || count == mOutputWindowSize) {
            if (output != NULL) {
                // this indicates two cases:
                // 1) the next output POC is found.
                // 2) output queue is full and there is at least one buffer meeting the output criteria.
                mNextOutputPOC = output->pictureOrder + 1;
                break;
            } else {
                // this indicates output queue is full and no buffer in the queue meets the output criteria
                // restart processing as queue is FULL and output criteria is changed. (next output POC is 0)
                mNextOutputPOC = MINIMUM_POC;
                count = 0;
                poc = MAXIMUM_POC;
                p = mOutputHead;
                continue;
            }
        }
        if (p->next == NULL) {
            output = NULL;
        }

        p = p->next;
    } while (p != NULL);

    if (draining == true && output == NULL) {
        output = outputleastpoc;
    }

    return output;
}
#endif

bool VideoDecoderBase::checkBufferAvail(void) {
    if (!mInitialized) {
        if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) == 0) {
            return true;
        }
        for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
            if (mSignalBufferPre[i] != NULL) {
                return true;
            }
        }
        return false;
    }
    // check whether there is buffer available for decoding
    // TODO: check frame being referenced for frame skipping
    VideoSurfaceBuffer *buffer = NULL;
    for (int32_t i = 0; i < mNumSurfaces; i++) {
        buffer = mSurfaceBuffers + i;

        if (buffer->asReferernce == false &&
            buffer->renderBuffer.renderDone == true) {
            querySurfaceRenderStatus(buffer);
            if (buffer->renderBuffer.driverRenderDone == true)
                return true;
        }
     }
    return false;
}

Decode_Status VideoDecoderBase::acquireSurfaceBuffer(void) {
    if (mVAStarted == false) {
        return DECODE_FAIL;
    }

    if (mAcquiredBuffer != NULL) {
        ETRACE("mAcquiredBuffer is not NULL. Implementation bug.");
        return DECODE_FAIL;
    }

    int nextAcquire = mSurfaceAcquirePos;
    VideoSurfaceBuffer *acquiredBuffer = NULL;
    bool acquired = false;

    while (acquired == false) {
        acquiredBuffer = mSurfaceBuffers + nextAcquire;

        querySurfaceRenderStatus(acquiredBuffer);

        if (acquiredBuffer->asReferernce == false && acquiredBuffer->renderBuffer.renderDone == true && acquiredBuffer->renderBuffer.driverRenderDone == true) {
            // this is potential buffer for acquisition. Check if it is referenced by other surface for frame skipping
            VideoSurfaceBuffer *temp;
            acquired = true;
            for (int i = 0; i < mNumSurfaces; i++) {
                if (i == nextAcquire) {
                    continue;
                }
                temp = mSurfaceBuffers + i;
                // use mSurfaces[nextAcquire] instead of acquiredBuffer->renderBuffer.surface as its the actual surface to use.
                if (temp->renderBuffer.surface == mSurfaces[nextAcquire] &&
                    temp->renderBuffer.renderDone == false) {
                    ITRACE("Surface is referenced by other surface buffer.");
                    acquired = false;
                    break;
                }
            }
        }
        if (acquired) {
            break;
        }
        nextAcquire++;
        if (nextAcquire == mNumSurfaces) {
            nextAcquire = 0;
        }
        if (nextAcquire == mSurfaceAcquirePos) {
            return DECODE_NO_SURFACE;
        }
    }

    if (acquired == false) {
        return DECODE_NO_SURFACE;
    }

    mAcquiredBuffer = acquiredBuffer;
    mSurfaceAcquirePos = nextAcquire;

    // set surface again as surface maybe reset by skipped frame.
    // skipped frame is a "non-coded frame" and decoder needs to duplicate the previous reference frame as the output.
    mAcquiredBuffer->renderBuffer.surface = mSurfaces[mSurfaceAcquirePos];
    if (mSurfaceUserPtr && mAcquiredBuffer->mappedData) {
        mAcquiredBuffer->mappedData->data = mSurfaceUserPtr[mSurfaceAcquirePos];
    }
    mAcquiredBuffer->renderBuffer.timeStamp = INVALID_PTS;
    mAcquiredBuffer->renderBuffer.display = mVADisplay;
    mAcquiredBuffer->renderBuffer.flag = 0;
    mAcquiredBuffer->renderBuffer.renderDone = false;
    mAcquiredBuffer->asReferernce = false;
    mAcquiredBuffer->renderBuffer.errBuf.errorNumber = 0;
    mAcquiredBuffer->renderBuffer.errBuf.timeStamp = INVALID_PTS;

    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderBase::outputSurfaceBuffer(void) {
    Decode_Status status;
    if (mAcquiredBuffer == NULL) {
        ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
        return DECODE_FAIL;
    }

    if (mRawOutput) {
        status = getRawDataFromSurface();
        CHECK_STATUS();
    }

    // frame is successfly decoded to the current surface,  it is ready for output
    if (mShowFrame) {
        mAcquiredBuffer->renderBuffer.renderDone = false;
    } else {
        mAcquiredBuffer->renderBuffer.renderDone = true;
    }

    // decoder must set "asReference and referenceFrame" flags properly

    // update reference frames
    if (mAcquiredBuffer->referenceFrame) {
        if (mManageReference) {
            // managing reference for MPEG4/H.263/WMV.
            // AVC should manage reference frame in a different way
            if (mForwardReference != NULL) {
                // this foward reference is no longer needed
                mForwardReference->asReferernce = false;
            }
            // Forware reference for either P or B frame prediction
            mForwardReference = mLastReference;
            mAcquiredBuffer->asReferernce = true;
        }

        // the last reference frame.
        mLastReference = mAcquiredBuffer;
    }
    // add to the output list
    if (mShowFrame) {
        if (mOutputHead == NULL) {
            mOutputHead = mAcquiredBuffer;
        } else {
            mOutputTail->next = mAcquiredBuffer;
        }
        mOutputTail = mAcquiredBuffer;
        mOutputTail->next = NULL;
    }

    //VTRACE("Pushing POC %d to queue (pts = %.2f)", mAcquiredBuffer->pictureOrder, mAcquiredBuffer->renderBuffer.timeStamp/1E6);

    mAcquiredBuffer = NULL;
    mSurfaceAcquirePos = (mSurfaceAcquirePos  + 1 ) % mNumSurfaces;
    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderBase::releaseSurfaceBuffer(void) {
    if (mAcquiredBuffer == NULL) {
        // this is harmless error
        return DECODE_SUCCESS;
    }

    // frame is not decoded to the acquired buffer, current surface is invalid, and can't be output.
    mAcquiredBuffer->asReferernce = false;
    mAcquiredBuffer->renderBuffer.renderDone = true;
    mAcquiredBuffer = NULL;
    return DECODE_SUCCESS;
}

void VideoDecoderBase::flushSurfaceBuffers(void) {
    endDecodingFrame(true);
    VideoSurfaceBuffer *p = NULL;
    while (mOutputHead) {
        mOutputHead->renderBuffer.renderDone = true;
        p = mOutputHead;
        mOutputHead = mOutputHead->next;
        p->next = NULL;
    }
    mOutputHead = NULL;
    mOutputTail = NULL;
}

Decode_Status VideoDecoderBase::endDecodingFrame(bool dropFrame) {
    Decode_Status status = DECODE_SUCCESS;
    VAStatus vaStatus;

    if (mDecodingFrame == false) {
        if (mAcquiredBuffer != NULL) {
            //ETRACE("mAcquiredBuffer is not NULL. Implementation bug.");
            releaseSurfaceBuffer();
            status = DECODE_FAIL;
        }
        return status;
    }
    // return through exit label to reset mDecodingFrame
    if (mAcquiredBuffer == NULL) {
        ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
        status = DECODE_FAIL;
        goto exit;
    }

    vaStatus = vaEndPicture(mVADisplay, mVAContext);
    if (vaStatus != VA_STATUS_SUCCESS) {
        releaseSurfaceBuffer();
        ETRACE("vaEndPicture failed. vaStatus = %d", vaStatus);
        status = DECODE_DRIVER_FAIL;
        goto exit;
    }

    if (dropFrame) {
        // we are asked to drop this decoded picture
        VTRACE("Frame dropped in endDecodingFrame");
        vaStatus = vaSyncSurface(mVADisplay, mAcquiredBuffer->renderBuffer.surface);
        releaseSurfaceBuffer();
        goto exit;
    }
    status = outputSurfaceBuffer();
    // fall through
exit:
    mDecodingFrame = false;
    return status;
}


Decode_Status VideoDecoderBase::setupVA(uint32_t numSurface, VAProfile profile, uint32_t numExtraSurface) {
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    Decode_Status status;

    if (mVAStarted) {
        return DECODE_SUCCESS;
    }

    mRotationDegrees = 0;
    if (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER){
#ifdef TARGET_HAS_ISV
        if (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber - mConfigBuffer.vppBufferNum)
#else
        if (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber)
#endif
            return DECODE_FORMAT_CHANGE;

        numSurface = mConfigBuffer.surfaceNumber;
        // if format has been changed in USE_NATIVE_GRAPHIC_BUFFER mode,
        // we can not setupVA here when the graphic buffer resolution is smaller than the resolution decoder really needs
        if (mSizeChanged) {
            if (mStoreMetaData || (!mStoreMetaData && (mVideoFormatInfo.surfaceWidth < mVideoFormatInfo.width || mVideoFormatInfo.surfaceHeight < mVideoFormatInfo.height))) {
                mSizeChanged = false;
                return DECODE_FORMAT_CHANGE;
            }
        }
    }

    // TODO: validate profile
    if (numSurface == 0) {
        return DECODE_FAIL;
    }

    if (mConfigBuffer.flag & HAS_MINIMUM_SURFACE_NUMBER) {
        if (numSurface < mConfigBuffer.surfaceNumber) {
            WTRACE("surface to allocated %d is less than minimum number required %d",
                    numSurface, mConfigBuffer.surfaceNumber);
            numSurface = mConfigBuffer.surfaceNumber;
        }
    }

    if (mVADisplay != NULL) {
        ETRACE("VA is partially started.");
        return DECODE_FAIL;
    }

    // Display is defined as "unsigned int"
#ifndef USE_HYBRID_DRIVER
    mDisplay = new Display;
    *mDisplay = ANDROID_DISPLAY_HANDLE;
#else
    if (profile >= VAProfileH264Baseline && profile <= VAProfileVC1Advanced) {
        ITRACE("Using GEN driver");
        mDisplay = "libva_driver_name=i965";
        mUseGEN = true;
    } else {
        ITRACE("Using PVR driver");
        mDisplay = "libva_driver_name=pvr";
        mUseGEN = false;
    }
#endif
    mVADisplay = vaGetDisplay(mDisplay);
    if (mVADisplay == NULL) {
        ETRACE("vaGetDisplay failed.");
        return DECODE_DRIVER_FAIL;
    }

    int majorVersion, minorVersion;
    vaStatus = vaInitialize(mVADisplay, &majorVersion, &minorVersion);
    CHECK_VA_STATUS("vaInitialize");

    if ((int32_t)profile != VAProfileSoftwareDecoding) {

        status = checkHardwareCapability();
        CHECK_STATUS("checkHardwareCapability");

#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
        status = getCodecSpecificConfigs(profile, &mVAConfig);
        CHECK_STATUS("getCodecSpecificAttributes");
#else
        VAConfigAttrib attrib;
        //We are requesting RT attributes
        attrib.type = VAConfigAttribRTFormat;
        attrib.value = VA_RT_FORMAT_YUV420;

        vaStatus = vaCreateConfig(
                mVADisplay,
                profile,
                VAEntrypointVLD,
                &attrib,
                1,
                &mVAConfig);
        CHECK_VA_STATUS("vaCreateConfig");
#endif
    }

    mNumSurfaces = numSurface;
    mNumExtraSurfaces = numExtraSurface;
    mSurfaces = new VASurfaceID [mNumSurfaces + mNumExtraSurfaces];
    mExtraSurfaces = mSurfaces + mNumSurfaces;
    for (int i = 0; i < mNumSurfaces + mNumExtraSurfaces; ++i) {
        mSurfaces[i] = VA_INVALID_SURFACE;
    }
    if (mSurfaces == NULL) {
        return DECODE_MEMORY_FAIL;
    }

    setRenderRect();
    setColorSpaceInfo(mVideoFormatInfo.colorMatrix, mVideoFormatInfo.videoRange);

    int32_t format = VA_RT_FORMAT_YUV420;
    if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION) {
#ifndef USE_AVC_SHORT_FORMAT
        format |= VA_RT_FORMAT_PROTECTED;
        WTRACE("Surface is protected.");
#endif
    }
    if (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) {
        if (!mStoreMetaData) {
            VASurfaceAttrib attribs[2];
            mVASurfaceAttrib = new VASurfaceAttribExternalBuffers;
            if (mVASurfaceAttrib == NULL) {
                return DECODE_MEMORY_FAIL;
            }

            mVASurfaceAttrib->buffers= (unsigned long *)malloc(sizeof(unsigned long)*mNumSurfaces);
            if (mVASurfaceAttrib->buffers == NULL) {
                return DECODE_MEMORY_FAIL;
            }
            mVASurfaceAttrib->num_buffers = mNumSurfaces;
            mVASurfaceAttrib->pixel_format = VA_FOURCC_NV12;
            mVASurfaceAttrib->width = mVideoFormatInfo.surfaceWidth;
            mVASurfaceAttrib->height = mVideoFormatInfo.surfaceHeight;
            mVASurfaceAttrib->data_size = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride * 1.5;
            mVASurfaceAttrib->num_planes = 2;
            mVASurfaceAttrib->pitches[0] = mConfigBuffer.graphicBufferHStride;
            mVASurfaceAttrib->pitches[1] = mConfigBuffer.graphicBufferHStride;
            mVASurfaceAttrib->pitches[2] = 0;
            mVASurfaceAttrib->pitches[3] = 0;
            mVASurfaceAttrib->offsets[0] = 0;
            mVASurfaceAttrib->offsets[1] = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride;
            mVASurfaceAttrib->offsets[2] = 0;
            mVASurfaceAttrib->offsets[3] = 0;
            mVASurfaceAttrib->private_data = (void *)mConfigBuffer.nativeWindow;
            mVASurfaceAttrib->flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
            if (mConfigBuffer.flag & USE_TILING_MEMORY)
                mVASurfaceAttrib->flags |= VA_SURFACE_EXTBUF_DESC_ENABLE_TILING;

            for (int i = 0; i < mNumSurfaces; i++) {
                mVASurfaceAttrib->buffers[i] = (unsigned long)mConfigBuffer.graphicBufferHandler[i];
            }

            attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
            attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
            attribs[0].value.type = VAGenericValueTypeInteger;
            attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;

            attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
            attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
            attribs[1].value.type = VAGenericValueTypePointer;
            attribs[1].value.value.p = (void *)mVASurfaceAttrib;

            vaStatus = vaCreateSurfaces(
                mVADisplay,
                format,
                mVideoFormatInfo.surfaceWidth,
                mVideoFormatInfo.surfaceHeight,
                mSurfaces,
                mNumSurfaces,
                attribs,
                2);
        }
    } else {
        vaStatus = vaCreateSurfaces(
            mVADisplay,
            format,
            mVideoFormatInfo.width,
            mVideoFormatInfo.height,
            mSurfaces,
            mNumSurfaces,
            NULL,
            0);
        mVideoFormatInfo.surfaceWidth = mVideoFormatInfo.width;
        mVideoFormatInfo.surfaceHeight = mVideoFormatInfo.height;
    }
    CHECK_VA_STATUS("vaCreateSurfaces");

    if (mNumExtraSurfaces != 0) {
        vaStatus = vaCreateSurfaces(
            mVADisplay,
            format,
            mVideoFormatInfo.surfaceWidth,
            mVideoFormatInfo.surfaceHeight,
            mExtraSurfaces,
            mNumExtraSurfaces,
            NULL,
            0);
        CHECK_VA_STATUS("vaCreateSurfaces");
    }

    mVideoFormatInfo.surfaceNumber = mNumSurfaces;
    mVideoFormatInfo.ctxSurfaces = mSurfaces;

    if ((int32_t)profile != VAProfileSoftwareDecoding) {
        if (mStoreMetaData) {
            if (mUseGEN) {
                vaStatus = vaCreateContext(
                    mVADisplay,
                    mVAConfig,
                    mVideoFormatInfo.surfaceWidth,
                    mVideoFormatInfo.surfaceHeight,
                    0,
                    NULL,
                    0,
                    &mVAContext);
            } else {
                vaStatus = vaCreateContext(
                    mVADisplay,
                    mVAConfig,
                    mVideoFormatInfo.surfaceWidth,
                    mVideoFormatInfo.surfaceHeight,
                    0,
                    NULL,
                    mNumSurfaces + mNumExtraSurfaces,
                    &mVAContext);
            }
        } else {
            vaStatus = vaCreateContext(
                mVADisplay,
                mVAConfig,
                mVideoFormatInfo.surfaceWidth,
                mVideoFormatInfo.surfaceHeight,
                0,
                mSurfaces,
                mNumSurfaces + mNumExtraSurfaces,
                &mVAContext);
        }
        CHECK_VA_STATUS("vaCreateContext");
    }

    mSurfaceBuffers = new VideoSurfaceBuffer [mNumSurfaces];
    if (mSurfaceBuffers == NULL) {
        return DECODE_MEMORY_FAIL;
    }
    initSurfaceBuffer(true);

    if ((int32_t)profile == VAProfileSoftwareDecoding) {
        // derive user pointer from surface for direct access
        status = mapSurface();
        CHECK_STATUS("mapSurface")
    }

    setRotationDegrees(mConfigBuffer.rotationDegrees);

    mVAStarted = true;

    pthread_mutex_lock(&mLock);
    if (mStoreMetaData) {
        for (uint32_t i = 0; i < mMetaDataBuffersNum; i++) {
            status = createSurfaceFromHandle(i);
            CHECK_STATUS("createSurfaceFromHandle");
            mSurfaceBuffers[i].renderBuffer.graphicBufferIndex = i;
        }
    }
    pthread_mutex_unlock(&mLock);

    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderBase::terminateVA(void) {
    mSignalBufferSize = 0;
    for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
         mSignalBufferPre[i] = NULL;
    }

    if (mVAStarted == false) {
        // VA hasn't been started yet
        return DECODE_SUCCESS;
    }

    if (mSurfaceBuffers) {
        for (int32_t i = 0; i < mNumSurfaces; i++) {
            if (mSurfaceBuffers[i].renderBuffer.rawData) {
                if (mSurfaceBuffers[i].renderBuffer.rawData->data) {
                    delete [] mSurfaceBuffers[i].renderBuffer.rawData->data;
                }
                delete mSurfaceBuffers[i].renderBuffer.rawData;
            }
            if (mSurfaceBuffers[i].mappedData) {
                // don't  delete data pointer as it is mapped from surface
                delete mSurfaceBuffers[i].mappedData;
            }
        }
        delete [] mSurfaceBuffers;
        mSurfaceBuffers = NULL;
    }

    if (mVASurfaceAttrib) {
        if (mVASurfaceAttrib->buffers) free(mVASurfaceAttrib->buffers);
        delete mVASurfaceAttrib;
        mVASurfaceAttrib = NULL;
    }


    if (mSurfaceUserPtr) {
        delete [] mSurfaceUserPtr;
        mSurfaceUserPtr = NULL;
    }

    if (mSurfaces) {
        vaDestroySurfaces(mVADisplay, mSurfaces, mStoreMetaData ? mMetaDataBuffersNum : (mNumSurfaces + mNumExtraSurfaces));
        delete [] mSurfaces;
        mSurfaces = NULL;
    }

    if (mVAContext != VA_INVALID_ID) {
         vaDestroyContext(mVADisplay, mVAContext);
         mVAContext = VA_INVALID_ID;
    }

    if (mVAConfig != VA_INVALID_ID) {
        vaDestroyConfig(mVADisplay, mVAConfig);
        mVAConfig = VA_INVALID_ID;
    }

    if (mVADisplay) {
        vaTerminate(mVADisplay);
        mVADisplay = NULL;
    }

    if (mDisplay) {
#ifndef USE_HYBRID_DRIVER
        delete mDisplay;
#endif
        mDisplay = NULL;
    }

    mVAStarted = false;
    mInitialized = false;
    mErrReportEnabled = false;
    if (mStoreMetaData) {
        mMetaDataBuffersNum = 0;
        mSurfaceAcquirePos = 0;
    }
    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderBase::parseBuffer(uint8_t *buffer, int32_t size, bool config, void** vbpData) {
     // DON'T check if mVAStarted == true
    if (mParserHandle == NULL) {
        return DECODE_NO_PARSER;
    }

    uint32_t vbpStatus;
    if (buffer == NULL || size <= 0) {
        return DECODE_INVALID_DATA;
    }

    uint8_t configFlag = config ? 1 : 0;
    vbpStatus = mParserParse(mParserHandle, buffer, size, configFlag);
    CHECK_VBP_STATUS("vbp_parse");

    vbpStatus = mParserQuery(mParserHandle, vbpData);
    CHECK_VBP_STATUS("vbp_query");

    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderBase::mapSurface(void) {
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    VAImage image;
    uint8_t *userPtr;
    mSurfaceUserPtr = new uint8_t* [mNumSurfaces];
    if (mSurfaceUserPtr == NULL) {
        return DECODE_MEMORY_FAIL;
    }

    for (int32_t i = 0; i< mNumSurfaces; i++) {
        vaStatus = vaDeriveImage(mVADisplay, mSurfaces[i], &image);
        CHECK_VA_STATUS("vaDeriveImage");
        vaStatus = vaMapBuffer(mVADisplay, image.buf, (void**)&userPtr);
        CHECK_VA_STATUS("vaMapBuffer");
        mSurfaceUserPtr[i] = userPtr;
        mSurfaceBuffers[i].mappedData = new VideoFrameRawData;
        if (mSurfaceBuffers[i].mappedData == NULL) {
            return DECODE_MEMORY_FAIL;
        }
        mSurfaceBuffers[i].mappedData->own = false; // derived from surface so can't be released
        mSurfaceBuffers[i].mappedData->data = NULL;  // specified during acquireSurfaceBuffer
        mSurfaceBuffers[i].mappedData->fourcc = image.format.fourcc;
        mSurfaceBuffers[i].mappedData->width = mVideoFormatInfo.width;
        mSurfaceBuffers[i].mappedData->height = mVideoFormatInfo.height;
        mSurfaceBuffers[i].mappedData->size = image.data_size;
        for (int pi = 0; pi < 3; pi++) {
            mSurfaceBuffers[i].mappedData->pitch[pi] = image.pitches[pi];
            mSurfaceBuffers[i].mappedData->offset[pi] = image.offsets[pi];
        }
        // debug information
        if (image.pitches[0] != image.pitches[1] ||
            image.width != mVideoFormatInfo.width ||
            image.height != mVideoFormatInfo.height ||
            image.offsets[0] != 0) {
            WTRACE("Unexpected VAImage format, w = %d, h = %d, offset = %d", image.width, image.height, image.offsets[0]);
        }
        // TODO: do we need to unmap buffer?
        //vaStatus = vaUnmapBuffer(mVADisplay, image.buf);
        //CHECK_VA_STATUS("vaMapBuffer");
        vaStatus = vaDestroyImage(mVADisplay,image.image_id);
        CHECK_VA_STATUS("vaDestroyImage");

    }
    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderBase::getRawDataFromSurface(VideoRenderBuffer *renderBuffer, uint8_t *pRawData, uint32_t *pSize, bool internal) {
    if (internal) {
        if (mAcquiredBuffer == NULL) {
            return DECODE_FAIL;
        }
        renderBuffer = &(mAcquiredBuffer->renderBuffer);
    }

    VAStatus vaStatus;
    VAImage vaImage;
    vaStatus = vaSyncSurface(renderBuffer->display, renderBuffer->surface);
    CHECK_VA_STATUS("vaSyncSurface");

    vaStatus = vaDeriveImage(renderBuffer->display, renderBuffer->surface, &vaImage);
    CHECK_VA_STATUS("vaDeriveImage");

    void *pBuf = NULL;
    vaStatus = vaMapBuffer(renderBuffer->display, vaImage.buf, &pBuf);
    CHECK_VA_STATUS("vaMapBuffer");


    // size in NV12 format
    uint32_t cropWidth = mVideoFormatInfo.width - (mVideoFormatInfo.cropLeft + mVideoFormatInfo.cropRight);
    uint32_t cropHeight = mVideoFormatInfo.height - (mVideoFormatInfo.cropBottom + mVideoFormatInfo.cropTop);
    if (strcasecmp(mVideoFormatInfo.mimeType,"video/avc") == 0 ||
        strcasecmp(mVideoFormatInfo.mimeType,"video/h264") == 0) {
        cropHeight = mVideoFormatInfo.height;
    }
    int32_t size = cropWidth  * cropHeight * 3 / 2;

    if (internal) {
        VideoFrameRawData *rawData = NULL;
        if (renderBuffer->rawData == NULL) {
            rawData = new VideoFrameRawData;
            if (rawData == NULL) {
                return DECODE_MEMORY_FAIL;
            }
            memset(rawData, 0, sizeof(VideoFrameRawData));
            renderBuffer->rawData = rawData;
        } else {
            rawData = renderBuffer->rawData;
        }

        if (rawData->data != NULL && rawData->size != size) {
            delete [] rawData->data;
            rawData->data = NULL;
            rawData->size = 0;
        }
        if (rawData->data == NULL) {
            rawData->data = new uint8_t [size];
            if (rawData->data == NULL) {
                return DECODE_MEMORY_FAIL;
            }
        }

        rawData->own = true; // allocated by this library
        rawData->width = cropWidth;
        rawData->height = cropHeight;
        rawData->pitch[0] = cropWidth;
        rawData->pitch[1] = cropWidth;
        rawData->pitch[2] = 0;  // interleaved U/V, two planes
        rawData->offset[0] = 0;
        rawData->offset[1] = cropWidth * cropHeight;
        rawData->offset[2] = cropWidth * cropHeight * 3 / 2;
        rawData->size = size;
        rawData->fourcc = 'NV12';

        pRawData = rawData->data;
    } else {
        *pSize = size;
    }

    if (size == (int32_t)vaImage.data_size) {
#ifdef  __SSE4_1__
        stream_memcpy(pRawData, pBuf, size);
#else
        memcpy(pRawData, pBuf, size);
#endif
    } else {
        // copy Y data
        uint8_t *src = (uint8_t*)pBuf;
        uint8_t *dst = pRawData;
        uint32_t row = 0;
        for (row = 0; row < cropHeight; row++) {
#ifdef  __SSE4_1__
            stream_memcpy(dst, src, cropWidth);
#else
            memcpy(dst, src, cropWidth);
#endif
            dst += cropWidth;
            src += vaImage.pitches[0];
        }
        // copy interleaved V and  U data
        src = (uint8_t*)pBuf + vaImage.offsets[1];
        for (row = 0; row < cropHeight / 2; row++) {
#ifdef  __SSE4_1__
            stream_memcpy(dst, src, cropWidth);
#else
            memcpy(dst, src, cropWidth);
#endif
            dst += cropWidth;
            src += vaImage.pitches[1];
        }
    }

    vaStatus = vaUnmapBuffer(renderBuffer->display, vaImage.buf);
    CHECK_VA_STATUS("vaUnmapBuffer");

    vaStatus = vaDestroyImage(renderBuffer->display, vaImage.image_id);
    CHECK_VA_STATUS("vaDestroyImage");

    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderBase::createSurfaceFromHandle(int index) {
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    Decode_Status status;

    int32_t format = VA_RT_FORMAT_YUV420;
    if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION) {
#ifndef USE_AVC_SHORT_FORMAT
        format |= VA_RT_FORMAT_PROTECTED;
        WTRACE("Surface is protected.");
#endif
    }
    VASurfaceAttrib attribs[2];
    VASurfaceAttribExternalBuffers surfExtBuf;
    surfExtBuf.num_buffers = 1;
    surfExtBuf.pixel_format = VA_FOURCC_NV12;
    surfExtBuf.width = mVideoFormatInfo.surfaceWidth;
    surfExtBuf.height = mVideoFormatInfo.surfaceHeight;
    surfExtBuf.data_size = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride * 1.5;
    surfExtBuf.num_planes = 2;
    surfExtBuf.pitches[0] = mConfigBuffer.graphicBufferHStride;
    surfExtBuf.pitches[1] = mConfigBuffer.graphicBufferHStride;
    surfExtBuf.pitches[2] = 0;
    surfExtBuf.pitches[3] = 0;
    surfExtBuf.offsets[0] = 0;
    surfExtBuf.offsets[1] = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride;
    surfExtBuf.offsets[2] = 0;
    surfExtBuf.offsets[3] = 0;
    surfExtBuf.private_data = (void *)mConfigBuffer.nativeWindow;
    surfExtBuf.flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
    if (mConfigBuffer.flag & USE_TILING_MEMORY) {
        surfExtBuf.flags |= VA_SURFACE_EXTBUF_DESC_ENABLE_TILING;
    }

    surfExtBuf.buffers = (long unsigned int*)&(mConfigBuffer.graphicBufferHandler[index]);

    attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
    attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
    attribs[0].value.type = VAGenericValueTypeInteger;
    attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;

    attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
    attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
    attribs[1].value.type = VAGenericValueTypePointer;
    attribs[1].value.value.p = (void *)&surfExtBuf;

    vaStatus = vaCreateSurfaces(
            mVADisplay,
            format,
            mVideoFormatInfo.surfaceWidth,
            mVideoFormatInfo.surfaceHeight,
            &(mSurfaces[index]),
            1,
            attribs,
        2);
    CHECK_VA_STATUS("vaCreateSurfaces");

    return DECODE_SUCCESS;
}

void VideoDecoderBase::initSurfaceBuffer(bool reset) {
    bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
    if (useGraphicBuffer && reset) {
        pthread_mutex_lock(&mLock);
    }
    for (int32_t i = 0; i < mNumSurfaces; i++) {
        mSurfaceBuffers[i].renderBuffer.display = mVADisplay;
        mSurfaceBuffers[i].renderBuffer.surface = VA_INVALID_SURFACE;  // set in acquireSurfaceBuffer
        mSurfaceBuffers[i].renderBuffer.flag = 0;
        mSurfaceBuffers[i].renderBuffer.scanFormat = VA_FRAME_PICTURE;
        mSurfaceBuffers[i].renderBuffer.timeStamp = 0;
        mSurfaceBuffers[i].referenceFrame = false;
        mSurfaceBuffers[i].asReferernce= false;
        mSurfaceBuffers[i].pictureOrder = 0;
        mSurfaceBuffers[i].next = NULL;
        if (reset == true) {
            mSurfaceBuffers[i].renderBuffer.rawData = NULL;
            mSurfaceBuffers[i].mappedData = NULL;
        }
        if (useGraphicBuffer) {
            if (reset) {
               mSurfaceBuffers[i].renderBuffer.graphicBufferHandle = mConfigBuffer.graphicBufferHandler[i];
               mSurfaceBuffers[i].renderBuffer.renderDone = false; //default false
               for (uint32_t j = 0; j < mSignalBufferSize; j++) {
                   if(mSignalBufferPre[j] != NULL && mSignalBufferPre[j] == mSurfaceBuffers[i].renderBuffer.graphicBufferHandle) {
                      mSurfaceBuffers[i].renderBuffer.renderDone = true;
                      VTRACE("initSurfaceBuffer set renderDone = true index = %d", i);
                      mSignalBufferPre[j] = NULL;
                      break;
                   }
               }
            } else {
               mSurfaceBuffers[i].renderBuffer.renderDone = false;
            }
        } else {
            mSurfaceBuffers[i].renderBuffer.graphicBufferHandle = NULL;
            mSurfaceBuffers[i].renderBuffer.renderDone = true;
        }
        mSurfaceBuffers[i].renderBuffer.graphicBufferIndex = i;
    }

    if (useGraphicBuffer && reset) {
        mInitialized = true;
        mSignalBufferSize = 0;
        pthread_mutex_unlock(&mLock);
    }
}

Decode_Status VideoDecoderBase::signalRenderDone(void * graphichandler, bool isNew) {
    Decode_Status status;
    if (graphichandler == NULL) {
        return DECODE_SUCCESS;
    }
    pthread_mutex_lock(&mLock);
    bool graphicBufferMode = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
    if (mStoreMetaData) {
        if (!graphicBufferMode) {
            pthread_mutex_unlock(&mLock);
            return DECODE_SUCCESS;
        }

        if ((mMetaDataBuffersNum < mConfigBuffer.surfaceNumber) && isNew) {
            mConfigBuffer.graphicBufferHandler[mMetaDataBuffersNum] = graphichandler;
            if (mInitialized) {
                mSurfaceBuffers[mMetaDataBuffersNum].renderBuffer.graphicBufferHandle = graphichandler;
                mSurfaceBuffers[mMetaDataBuffersNum].renderBuffer.graphicBufferIndex = mMetaDataBuffersNum;
            }
        }
    }
    int i = 0;
    if (!mInitialized) {
        if (mSignalBufferSize >= MAX_GRAPHIC_BUFFER_NUM) {
            pthread_mutex_unlock(&mLock);
            return DECODE_INVALID_DATA;
        }
        mSignalBufferPre[mSignalBufferSize++] = graphichandler;
        VTRACE("SignalRenderDoneFlag mInitialized = false graphichandler = %p, mSignalBufferSize = %d", graphichandler, mSignalBufferSize);
    } else {
        if (!graphicBufferMode) {
            pthread_mutex_unlock(&mLock);
            return DECODE_SUCCESS;
        }
        if (mStoreMetaData) {
            if ((mMetaDataBuffersNum < mConfigBuffer.surfaceNumber) && isNew) {
                if (mVAStarted) {
                    status = createSurfaceFromHandle(mMetaDataBuffersNum);
                    CHECK_STATUS("createSurfaceFromHandle")
                }
            }
        }
        for (i = 0; i < mNumSurfaces; i++) {
            if (mSurfaceBuffers[i].renderBuffer.graphicBufferHandle == graphichandler) {
                mSurfaceBuffers[i].renderBuffer.renderDone = true;
                VTRACE("SignalRenderDoneFlag mInitialized = true index = %d", i);
               break;
           }
        }
    }

    if (mStoreMetaData) {
        if ((mMetaDataBuffersNum < mConfigBuffer.surfaceNumber) && isNew) {
            mMetaDataBuffersNum++;
        }
    }

    pthread_mutex_unlock(&mLock);

    return DECODE_SUCCESS;

}

void VideoDecoderBase::querySurfaceRenderStatus(VideoSurfaceBuffer* surface) {
    VASurfaceStatus surfStat = VASurfaceReady;
    VAStatus    vaStat = VA_STATUS_SUCCESS;

    if (!surface) {
        LOGW("SurfaceBuffer not ready yet");
        return;
    }
    surface->renderBuffer.driverRenderDone = true;

#ifndef USE_GEN_HW
    if (surface->renderBuffer.surface != VA_INVALID_SURFACE &&
       (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) {

        vaStat = vaQuerySurfaceStatus(mVADisplay, surface->renderBuffer.surface, &surfStat);

        if ((vaStat == VA_STATUS_SUCCESS) && (surfStat != VASurfaceReady))
            surface->renderBuffer.driverRenderDone = false;

    }
#endif

}

// This function should be called before start() to load different type of parsers
#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
Decode_Status VideoDecoderBase::setParserType(_vbp_parser_type type) {
    if ((int32_t)type != VBP_INVALID) {
        ITRACE("Parser Type = %d", (int32_t)type);
        mParserType = type;
        return DECODE_SUCCESS;
    } else {
        ETRACE("Invalid parser type = %d", (int32_t)type);
        return DECODE_NO_PARSER;
    }
}

Decode_Status VideoDecoderBase::updateBuffer(uint8_t *buffer, int32_t size, void** vbpData) {
    if (mParserHandle == NULL) {
        return DECODE_NO_PARSER;
    }

    uint32_t vbpStatus;
    if (buffer == NULL || size <= 0) {
        return DECODE_INVALID_DATA;
    }

    vbpStatus = mParserUpdate(mParserHandle, buffer, size, vbpData);
    CHECK_VBP_STATUS("vbp_update");

    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderBase::queryBuffer(void** vbpData) {
    if (mParserHandle == NULL) {
        return DECODE_NO_PARSER;
    }

    uint32_t vbpStatus;
    vbpStatus = mParserQuery(mParserHandle, vbpData);
    CHECK_VBP_STATUS("vbp_query");

    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderBase::getCodecSpecificConfigs(VAProfile profile, VAConfigID *config) {
    VAStatus vaStatus;
    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    attrib.value = VA_RT_FORMAT_YUV420;

    if (config == NULL) {
        ETRACE("Invalid parameter!");
        return DECODE_FAIL;
    }

    vaStatus = vaCreateConfig(
            mVADisplay,
            profile,
            VAEntrypointVLD,
            &attrib,
            1,
            config);

    CHECK_VA_STATUS("vaCreateConfig");

    return DECODE_SUCCESS;
}
#endif
Decode_Status VideoDecoderBase::checkHardwareCapability() {
    return DECODE_SUCCESS;
}

void VideoDecoderBase::drainDecodingErrors(VideoErrorBuffer *outErrBuf, VideoRenderBuffer *currentSurface) {
    if (mErrReportEnabled && outErrBuf && currentSurface) {
        memcpy(outErrBuf, &(currentSurface->errBuf), sizeof(VideoErrorBuffer));

        currentSurface->errBuf.errorNumber = 0;
        currentSurface->errBuf.timeStamp = INVALID_PTS;
    }
    if (outErrBuf)
        VTRACE("%s: error number is %d", __FUNCTION__, outErrBuf->errorNumber);
}

void VideoDecoderBase::fillDecodingErrors(VideoRenderBuffer *currentSurface) {
    VAStatus ret;

    if (mErrReportEnabled) {
        currentSurface->errBuf.timeStamp = currentSurface->timeStamp;
        // TODO: is 10 a suitable number?
        VASurfaceDecodeMBErrors *err_drv_output = NULL;
        ret = vaQuerySurfaceError(mVADisplay, currentSurface->surface, VA_STATUS_ERROR_DECODING_ERROR, (void **)&err_drv_output);
        if (ret || !err_drv_output) {
            WTRACE("vaQuerySurfaceError failed.");
            return;
        }

        int offset =  0x1 & currentSurface->errBuf.errorNumber;// offset is either 0 or 1
        for (int i = 0; i < MAX_ERR_NUM - offset; i++) {
            if (err_drv_output[i].status != -1) {
                currentSurface->errBuf.errorNumber++;
                currentSurface->errBuf.errorArray[i + offset].type = DecodeMBError;
                currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.start_mb = err_drv_output[i].start_mb;
                currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.end_mb = err_drv_output[i].end_mb;
                currentSurface->errBuf.errorArray[i + offset].num_mbs = err_drv_output[i].end_mb - err_drv_output[i].start_mb + 1;
                ITRACE("Error Index[%d]: type = %d, start_mb = %d, end_mb = %d",
                    currentSurface->errBuf.errorNumber - 1,
                    currentSurface->errBuf.errorArray[i + offset].type,
                    currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.start_mb,
                    currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.end_mb);
            } else break;
        }
        ITRACE("%s: error number of current surface is %d, timestamp @%llu",
            __FUNCTION__, currentSurface->errBuf.errorNumber, currentSurface->timeStamp);
    }
}

void VideoDecoderBase::setRotationDegrees(int32_t rotationDegrees) {
    if (mRotationDegrees == rotationDegrees) {
        return;
    }

    ITRACE("set new rotation degree: %d", rotationDegrees);
    VADisplayAttribute rotate;
    rotate.type = VADisplayAttribRotation;
    rotate.value = VA_ROTATION_NONE;
    if (rotationDegrees == 0)
        rotate.value = VA_ROTATION_NONE;
    else if (rotationDegrees == 90)
        rotate.value = VA_ROTATION_90;
    else if (rotationDegrees == 180)
        rotate.value = VA_ROTATION_180;
    else if (rotationDegrees == 270)
        rotate.value = VA_ROTATION_270;

    VAStatus ret = vaSetDisplayAttributes(mVADisplay, &rotate, 1);
    if (ret) {
        ETRACE("Failed to set rotation degree.");
    }
    mRotationDegrees = rotationDegrees;
}

void VideoDecoderBase::setRenderRect() {

    if (!mVADisplay)
        return;

    VAStatus ret;
    VARectangle rect;
    rect.x = mVideoFormatInfo.cropLeft;
    rect.y = mVideoFormatInfo.cropTop;
    rect.width = mVideoFormatInfo.width - (mVideoFormatInfo.cropLeft + mVideoFormatInfo.cropRight);
    rect.height = mVideoFormatInfo.height - (mVideoFormatInfo.cropBottom + mVideoFormatInfo.cropTop);
    if (strcasecmp(mVideoFormatInfo.mimeType,"video/avc") == 0 ||
        strcasecmp(mVideoFormatInfo.mimeType,"video/h264") == 0) {
        rect.height = mVideoFormatInfo.height;
    }

    VADisplayAttribute render_rect;
    render_rect.type = VADisplayAttribRenderRect;
    render_rect.attrib_ptr = &rect;

    ret = vaSetDisplayAttributes(mVADisplay, &render_rect, 1);
    if (ret) {
        ETRACE("Failed to set rotation degree.");
    }
}

void VideoDecoderBase::setColorSpaceInfo(int32_t colorMatrix, int32_t videoRange) {
    ITRACE("set colorMatrix: 0x%x ", colorMatrix);
    VADisplayAttribute cm;
    cm.type = VADisplayAttribCSCMatrix;
    if (colorMatrix == VA_SRC_BT601) {
        cm.attrib_ptr = &s601;
    } else if (colorMatrix == VA_SRC_BT709) {
        cm.attrib_ptr = &s709;
    } else {
      // if we can't get the color matrix or it's not BT601 or BT709
      // we decide the color matrix according to clip resolution
      if (mVideoFormatInfo.width < 1280 && mVideoFormatInfo.height < 720)
          cm.attrib_ptr = &s601;
      else
          cm.attrib_ptr = &s709;
    }

    VAStatus ret = vaSetDisplayAttributes(mVADisplay, &cm, 1);

    if (ret) {
        ETRACE("Failed to set colorMatrix.");
    }

    // 1: full range, 0: reduced range
    ITRACE("set videoRange: %d ", videoRange);
    VADisplayAttribute vr;
    vr.type = VADisplayAttribColorRange;
    vr.value = (videoRange == 1) ? VA_SOURCE_RANGE_FULL : VA_SOURCE_RANGE_REDUCED;

    ret = vaSetDisplayAttributes(mVADisplay, &vr, 1);

    if (ret) {
        ETRACE("Failed to set videoRange.");
    }
}
