182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON/*
282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Licensed under the Apache License, Version 2.0 (the "License");
582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* you may not use this file except in compliance with the License.
682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* You may obtain a copy of the License at
782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* http://www.apache.org/licenses/LICENSE-2.0
982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
1082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Unless required by applicable law or agreed to in writing, software
1182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* distributed under the License is distributed on an "AS IS" BASIS,
1282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* See the License for the specific language governing permissions and
1482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* limitations under the License.
1582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*/
1682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
1782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "VideoDecoderBase.h"
1882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "VideoDecoderTrace.h"
1982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <string.h>
2082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <va/va_android.h>
2182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <va/va_tpi.h>
2282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifdef  __SSE4_1__
2382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "use_util_sse4.h"
2482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
2582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define INVALID_PTS ((uint64_t)-1)
2782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define MAXIMUM_POC  0x7FFFFFFF
2882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define MINIMUM_POC  0x80000000
2982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define ANDROID_DISPLAY_HANDLE 0x18C34078
3082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderBase::VideoDecoderBase(const char *mimeType, _vbp_parser_type type)
3282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    : mInitialized(false),
3382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mLowDelay(false),
341175ce579a69e847027026f615a053af76b792d5Tianmi Chen      mStoreMetaData(false),
3582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mDisplay(NULL),
3682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVADisplay(NULL),
3782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVAContext(VA_INVALID_ID),
3882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVAConfig(VA_INVALID_ID),
3982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVAStarted(false),
4082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mCurrentPTS(INVALID_PTS),
4182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mAcquiredBuffer(NULL),
4282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mLastReference(NULL),
4382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mForwardReference(NULL),
4482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mDecodingFrame(false),
4582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSizeChanged(false),
4682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mShowFrame(true),
4782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mOutputWindowSize(OUTPUT_WINDOW_SIZE),
4882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mRotationDegrees(0),
4982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mErrReportEnabled(false),
5082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mWiDiOn(false),
5182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mRawOutput(false),
5282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mManageReference(true),
5382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mOutputMethod(OUTPUT_BY_PCT),
5482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mNumSurfaces(0),
5582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSurfaceBuffers(NULL),
5682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mOutputHead(NULL),
5782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mOutputTail(NULL),
5882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSurfaces(NULL),
5982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVASurfaceAttrib(NULL),
6082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSurfaceUserPtr(NULL),
6182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSurfaceAcquirePos(0),
6282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mNextOutputPOC(MINIMUM_POC),
6382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mParserType(type),
6482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mParserHandle(NULL),
6582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSignalBufferSize(0) {
6682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memset(&mVideoFormatInfo, 0, sizeof(VideoFormatInfo));
6882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memset(&mConfigBuffer, 0, sizeof(mConfigBuffer));
6982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
7082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         mSignalBufferPre[i] = NULL;
7182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
7282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_init(&mLock, NULL);
731175ce579a69e847027026f615a053af76b792d5Tianmi Chen    pthread_mutex_init(&mFormatLock, NULL);
7482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.mimeType = strdup(mimeType);
7582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mUseGEN = false;
761175ce579a69e847027026f615a053af76b792d5Tianmi Chen    mMetaDataBuffersNum = 0;
7782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLibHandle = NULL;
7882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserOpen = NULL;
7982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserClose = NULL;
8082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserParse = NULL;
8182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserQuery = NULL;
8282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserFlush = NULL;
8382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserUpdate = NULL;
8482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
8582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderBase::~VideoDecoderBase() {
8782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_destroy(&mLock);
881175ce579a69e847027026f615a053af76b792d5Tianmi Chen    pthread_mutex_destroy(&mFormatLock);
8982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    stop();
9082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    free(mVideoFormatInfo.mimeType);
9182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
9282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::start(VideoConfigBuffer *buffer) {
9482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer == NULL) {
9582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
9682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
9782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle != NULL) {
9982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("Decoder has already started.");
10082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
10182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
10282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLibHandle = dlopen("libmixvbp.so", RTLD_NOW);
10382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mLibHandle == NULL) {
10482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON       return DECODE_NO_PARSER;
10582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
10682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserOpen = (OpenFunc)dlsym(mLibHandle, "vbp_open");
10782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserClose = (CloseFunc)dlsym(mLibHandle, "vbp_close");
10882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserParse = (ParseFunc)dlsym(mLibHandle, "vbp_parse");
10982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserQuery = (QueryFunc)dlsym(mLibHandle, "vbp_query");
11082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserFlush = (FlushFunc)dlsym(mLibHandle, "vbp_flush");
11182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserOpen == NULL || mParserClose == NULL || mParserParse == NULL
11282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        || mParserQuery == NULL || mParserFlush == NULL) {
11382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
11482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
11582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
11682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserUpdate = (UpdateFunc)dlsym(mLibHandle, "vbp_update");
11782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserUpdate == NULL) {
11882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
11982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
12082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
12182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((int32_t)mParserType != VBP_INVALID) {
12282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("mParserType = %d", mParserType);
12382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mParserOpen(mParserType, &mParserHandle) != VBP_OK) {
12482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ETRACE("Failed to open VBP parser.");
12582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_NO_PARSER;
12682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
12782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
12882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // keep a copy of configure buffer, meta data only. It can be used to override VA setup parameter.
12982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer = *buffer;
13082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer.data = NULL;
13182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer.size = 0;
13282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
13382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.width = buffer->width;
13482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.height = buffer->height;
13582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) {
13682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceWidth = buffer->graphicBufferWidth;
13782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceHeight = buffer->graphicBufferHeight;
13882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
13982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLowDelay = buffer->flag & WANT_LOW_DELAY;
1401175ce579a69e847027026f615a053af76b792d5Tianmi Chen    mStoreMetaData = buffer->flag & WANT_STORE_META_DATA;
14182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mRawOutput = buffer->flag & WANT_RAW_OUTPUT;
14282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mRawOutput) {
14382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("Output is raw data.");
14482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
14582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
14782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
14882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::reset(VideoConfigBuffer *buffer) {
15182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer == NULL) {
15282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
15382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
15482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // if VA is already started, terminate VA as graphic buffers are reallocated by omxcodec
15682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    terminateVA();
15782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // reset the mconfigBuffer to pass it for startVA.
15982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer = *buffer;
16082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer.data = NULL;
16182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer.size = 0;
16282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
16382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.width = buffer->width;
16482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.height = buffer->height;
16582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) {
16682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceWidth = buffer->graphicBufferWidth;
16782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceHeight = buffer->graphicBufferHeight;
16882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
16982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.actualBufferNeeded = mConfigBuffer.surfaceNumber;
17082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLowDelay = buffer->flag & WANT_LOW_DELAY;
1711175ce579a69e847027026f615a053af76b792d5Tianmi Chen    mStoreMetaData = buffer->flag & WANT_STORE_META_DATA;
1721175ce579a69e847027026f615a053af76b792d5Tianmi Chen    mMetaDataBuffersNum = 0;
17382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mRawOutput = buffer->flag & WANT_RAW_OUTPUT;
17482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mRawOutput) {
17582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("Output is raw data.");
17682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
17782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
17882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
17982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::stop(void) {
18382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    terminateVA();
18482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mCurrentPTS = INVALID_PTS;
18682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer = NULL;
18782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastReference = NULL;
18882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mForwardReference = NULL;
18982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mDecodingFrame = false;
19082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSizeChanged = false;
19182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
19282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // private variables
19382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLowDelay = false;
1941175ce579a69e847027026f615a053af76b792d5Tianmi Chen    mStoreMetaData = false;
19582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mRawOutput = false;
19682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNumSurfaces = 0;
19782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceAcquirePos = 0;
19882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNextOutputPOC = MINIMUM_POC;
19982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.valid = false;
20082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle){
20182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mParserClose(mParserHandle);
20282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mParserHandle = NULL;
20382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
20482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mLibHandle) {
20582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dlclose(mLibHandle);
20682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mLibHandle = NULL;
20782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
20882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
20982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::flush(void) {
21182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted == false) {
21282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // nothing to flush at this stage
21382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return;
21482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
21582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    endDecodingFrame(true);
21782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = mOutputHead;
21982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // check if there's buffer with DRC flag in the output queue
22082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    while (p) {
22182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->renderBuffer.flag & IS_RESOLUTION_CHANGE) {
22282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSizeChanged = true;
22382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
22482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
22582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
22682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
22782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // avoid setting mSurfaceAcquirePos  to 0 as it may cause tearing
22882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // (surface is still being rendered)
22982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceAcquirePos = (mSurfaceAcquirePos  + 1) % mNumSurfaces;
23082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNextOutputPOC = MINIMUM_POC;
23182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mCurrentPTS = INVALID_PTS;
23282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer = NULL;
23382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastReference = NULL;
23482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mForwardReference = NULL;
23582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mOutputHead = NULL;
23682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mOutputTail = NULL;
23782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mDecodingFrame = false;
23882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // flush vbp parser
24082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle && (mParserFlush(mParserHandle) != VBP_OK)) {
24182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("Failed to flush parser. Continue");
24282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
24382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // initialize surface buffer without resetting mapped/raw data
24582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    initSurfaceBuffer(false);
24682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
24882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::freeSurfaceBuffers(void) {
25082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted == false) {
25182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // nothing to free surface buffers at this stage
25282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return;
25382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
25482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_lock(&mLock);
25682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    endDecodingFrame(true);
25882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // if VA is already started, terminate VA as graphic buffers are reallocated by omxcodec
26082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    terminateVA();
26182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_unlock(&mLock);
26382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
26482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONconst VideoFormatInfo* VideoDecoderBase::getFormatInfo(void) {
2661175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) && mStoreMetaData) {
2671175ce579a69e847027026f615a053af76b792d5Tianmi Chen        // Do nothing here, just to avoid thread
2681175ce579a69e847027026f615a053af76b792d5Tianmi Chen        // contention in updateFormatInfo()
2691175ce579a69e847027026f615a053af76b792d5Tianmi Chen        pthread_mutex_lock(&mFormatLock);
2701175ce579a69e847027026f615a053af76b792d5Tianmi Chen        pthread_mutex_unlock(&mFormatLock);
2711175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
2721175ce579a69e847027026f615a053af76b792d5Tianmi Chen
27382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return &mVideoFormatInfo;
27482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
27582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2761175ce579a69e847027026f615a053af76b792d5Tianmi Chenint VideoDecoderBase::getOutputQueueLength(void) {
2771175ce579a69e847027026f615a053af76b792d5Tianmi Chen    VideoSurfaceBuffer *p = mOutputHead;
2781175ce579a69e847027026f615a053af76b792d5Tianmi Chen
2791175ce579a69e847027026f615a053af76b792d5Tianmi Chen    int i = 0;
2801175ce579a69e847027026f615a053af76b792d5Tianmi Chen    while (p) {
2811175ce579a69e847027026f615a053af76b792d5Tianmi Chen        p = p->next;
2821175ce579a69e847027026f615a053af76b792d5Tianmi Chen        i++;
2831175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
2841175ce579a69e847027026f615a053af76b792d5Tianmi Chen
2851175ce579a69e847027026f615a053af76b792d5Tianmi Chen    return i;
2861175ce579a69e847027026f615a053af76b792d5Tianmi Chen}
2871175ce579a69e847027026f615a053af76b792d5Tianmi Chen
28882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONconst VideoRenderBuffer* VideoDecoderBase::getOutput(bool draining, VideoErrorBuffer *outErrBuf) {
28982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted == false) {
29082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return NULL;
29182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
29282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
29382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
29482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (draining) {
29582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // complete decoding the last frame and ignore return
29682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        endDecodingFrame(false);
29782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
29882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
29982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mOutputHead == NULL) {
30082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return NULL;
30182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
30282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
30382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output by position (the first buffer)
30482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputByPos = mOutputHead;
30582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
30682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mLowDelay) {
30782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputHead = mOutputHead->next;
30882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mOutputHead == NULL) {
30982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mOutputTail = NULL;
31082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
311661c5a76313015b6a3fea4b0e593b761a32f4372Andreas Gampe        vaSetTimestampForSurface(mVADisplay, outputByPos->renderBuffer.surface, outputByPos->renderBuffer.timeStamp);
31282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (useGraphicBuffer && !mUseGEN) {
31382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            vaSyncSurface(mVADisplay, outputByPos->renderBuffer.surface);
31482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            fillDecodingErrors(&(outputByPos->renderBuffer));
31582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
31682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (draining && mOutputTail == NULL) {
31782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outputByPos->renderBuffer.flag |= IS_EOS;
31882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
31982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        drainDecodingErrors(outErrBuf, &(outputByPos->renderBuffer));
32082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return &(outputByPos->renderBuffer);
32282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
32382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *output = NULL;
32582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mOutputMethod == OUTPUT_BY_POC) {
32682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        output = findOutputByPoc(draining);
32782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else if (mOutputMethod == OUTPUT_BY_PCT) {
32882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        output = findOutputByPct(draining);
32982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
33082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Invalid output method.");
33182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return NULL;
33282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
33382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (output == NULL) {
33582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return NULL;
33682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
33782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (output != outputByPos) {
33982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // remove this output from middle or end of the list
34082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VideoSurfaceBuffer *p = outputByPos;
34182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        while (p->next != output) {
34282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            p = p->next;
34382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
34482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p->next = output->next;
34582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mOutputTail == output) {
34682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mOutputTail = p;
34782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
34882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
34982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // remove this output from head of the list
35082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputHead = mOutputHead->next;
35182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mOutputHead == NULL) {
35282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mOutputTail = NULL;
35382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
35482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
35582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //VTRACE("Output POC %d for display (pts = %.2f)", output->pictureOrder, output->renderBuffer.timeStamp/1E6);
356661c5a76313015b6a3fea4b0e593b761a32f4372Andreas Gampe    vaSetTimestampForSurface(mVADisplay, output->renderBuffer.surface, output->renderBuffer.timeStamp);
35782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
35882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (useGraphicBuffer && !mUseGEN) {
35982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaSyncSurface(mVADisplay, output->renderBuffer.surface);
36082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        fillDecodingErrors(&(output->renderBuffer));
36182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
36282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
36382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (draining && mOutputTail == NULL) {
36482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        output->renderBuffer.flag |= IS_EOS;
36582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
36682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
36782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    drainDecodingErrors(outErrBuf, &(output->renderBuffer));
36882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
36982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return &(output->renderBuffer);
37082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
37182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
37282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoSurfaceBuffer* VideoDecoderBase::findOutputByPts() {
37382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output by presentation time stamp - buffer with the smallest time stamp is output
37482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = mOutputHead;
37582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputByPts = NULL;
37682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint64_t pts = INVALID_PTS;
37782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    do {
37882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if ((uint64_t)(p->renderBuffer.timeStamp) <= pts) {
37982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // find buffer with the smallest PTS
38082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            pts = p->renderBuffer.timeStamp;
38182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outputByPts = p;
38282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
38382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
38482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } while (p != NULL);
38582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
38682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return outputByPts;
38782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
38882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
38982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoSurfaceBuffer* VideoDecoderBase::findOutputByPct(bool draining) {
39082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output by picture coding type (PCT)
39182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // if there is more than one reference frame, the first reference frame is ouput, otherwise,
39282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output non-reference frame if there is any.
39382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
39482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = mOutputHead;
39582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputByPct = NULL;
39682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t reference = 0;
39782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    do {
39882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->referenceFrame) {
39982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            reference++;
40082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (reference > 1) {
40182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // mOutputHead must be a reference frame
40282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                outputByPct = mOutputHead;
40382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                break;
40482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
40582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
40682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // first non-reference frame
40782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outputByPct = p;
40882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
40982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
41082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
41182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } while (p != NULL);
41282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
41382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (outputByPct == NULL && draining) {
41482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        outputByPct = mOutputHead;
41582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
41682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return  outputByPct;
41782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
41882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
41982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if 0
42082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoSurfaceBuffer* VideoDecoderBase::findOutputByPoc(bool draining) {
42182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output by picture order count (POC)
42282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Output criteria:
42382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // if there is IDR frame (POC == 0), all the frames before IDR must be output;
42482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Otherwise, if draining flag is set or list is full, frame with the least POC is output;
42582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Otherwise, NOTHING is output
42682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
42782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t dpbFullness = 0;
42882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < mNumSurfaces; i++) {
42982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // count num of reference frames
43082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mSurfaceBuffers[i].asReferernce) {
43182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dpbFullness++;
43282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
43382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
43482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
43582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer && mAcquiredBuffer->asReferernce) {
43682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // frame is being decoded and is not ready for output yet
43782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dpbFullness--;
43882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
43982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
44082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = mOutputHead;
44182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    while (p != NULL) {
44282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // count dpbFullness with non-reference frame in the output queue
44382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->asReferernce == false) {
44482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dpbFullness++;
44582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
44682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
44782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
44882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
44982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONRetry:
45082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    p = mOutputHead;
45182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputByPoc = NULL;
45282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t count = 0;
45382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t poc = MAXIMUM_POC;
45482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    do {
45682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->pictureOrder == 0) {
45782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // output picture with the least POC before IDR
45882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (outputByPoc != NULL) {
45982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = outputByPoc->pictureOrder + 1;
46082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return outputByPoc;
46182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
46282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = MINIMUM_POC;
46382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
46482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
46582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
46682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // POC of  the output candidate must not be less than mNextOutputPOC
46782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->pictureOrder < mNextOutputPOC) {
46882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
46982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
47082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
47182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->pictureOrder < poc) {
47282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // update the least POC.
47382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            poc = p->pictureOrder;
47482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outputByPoc = p;
47582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
47682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        count++;
47782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
47882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } while (p != NULL && count < mOutputWindowSize);
47982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
48082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (draining == false && dpbFullness < mOutputWindowSize) {
48182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // list is not  full and we are not  in draining state
48282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // if DPB is already full, one frame must be output
48382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return NULL;
48482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
48582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
48682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (outputByPoc == NULL) {
48782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mNextOutputPOC = MINIMUM_POC;
48882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        goto Retry;
48982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
49082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
49182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // for debugging purpose
49282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (outputByPoc->pictureOrder != 0 && outputByPoc->pictureOrder < mNextOutputPOC) {
49382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Output POC is not incremental, expected %d, actual %d", mNextOutputPOC, outputByPoc->pictureOrder);
49482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        //gaps_in_frame_num_value_allowed_flag is not currently supported
49582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
49682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
49782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNextOutputPOC = outputByPoc->pictureOrder + 1;
49882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
49982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return outputByPoc;
50082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
50182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
50282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoSurfaceBuffer* VideoDecoderBase::findOutputByPoc(bool draining) {
50382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *output = NULL;
50482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = mOutputHead;
50582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t count = 0;
50682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t poc = MAXIMUM_POC;
50782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputleastpoc = mOutputHead;
50882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    do {
50982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        count++;
51082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->pictureOrder == 0) {
51182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // any picture before this POC (new IDR) must be output
51282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (output == NULL) {
51382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = MINIMUM_POC;
51482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // looking for any POC with negative value
51582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
51682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = output->pictureOrder + 1;
51782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                break;
51882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
51982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
52082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->pictureOrder < poc && p->pictureOrder >= mNextOutputPOC) {
52182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // this POC meets ouput criteria.
52282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            poc = p->pictureOrder;
52382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            output = p;
52482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outputleastpoc = p;
52582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
52682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (poc == mNextOutputPOC || count == mOutputWindowSize) {
52782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (output != NULL) {
52882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // this indicates two cases:
52982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // 1) the next output POC is found.
53082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // 2) output queue is full and there is at least one buffer meeting the output criteria.
53182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = output->pictureOrder + 1;
53282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                break;
53382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
53482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // this indicates output queue is full and no buffer in the queue meets the output criteria
53582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // restart processing as queue is FULL and output criteria is changed. (next output POC is 0)
53682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = MINIMUM_POC;
53782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                count = 0;
53882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                poc = MAXIMUM_POC;
53982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                p = mOutputHead;
54082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                continue;
54182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
54282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
54382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->next == NULL) {
54482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            output = NULL;
54582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
54682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
54782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
54882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } while (p != NULL);
54982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
55082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (draining == true && output == NULL) {
55182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        output = outputleastpoc;
55282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
55382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
55482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return output;
55582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
55682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
55782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
55882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONbool VideoDecoderBase::checkBufferAvail(void) {
55982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mInitialized) {
56082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) == 0) {
56182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return true;
56282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
56382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
56482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mSignalBufferPre[i] != NULL) {
56582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return true;
56682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
56782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
56882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return false;
56982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
57082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // check whether there is buffer available for decoding
57182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // TODO: check frame being referenced for frame skipping
57282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *buffer = NULL;
57382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < mNumSurfaces; i++) {
57482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        buffer = mSurfaceBuffers + i;
57582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
57682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (buffer->asReferernce == false &&
57782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            buffer->renderBuffer.renderDone == true) {
57882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            querySurfaceRenderStatus(buffer);
57982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (buffer->renderBuffer.driverRenderDone == true)
58082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return true;
58182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
58282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON     }
58382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return false;
58482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
58582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
58682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::acquireSurfaceBuffer(void) {
58782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted == false) {
58882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
58982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
59082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
59182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer != NULL) {
59282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("mAcquiredBuffer is not NULL. Implementation bug.");
59382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
59482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
59582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
59682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int nextAcquire = mSurfaceAcquirePos;
59782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *acquiredBuffer = NULL;
59882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool acquired = false;
59982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
60082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    while (acquired == false) {
60182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        acquiredBuffer = mSurfaceBuffers + nextAcquire;
60282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
60382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        querySurfaceRenderStatus(acquiredBuffer);
60482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
60582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (acquiredBuffer->asReferernce == false && acquiredBuffer->renderBuffer.renderDone == true && acquiredBuffer->renderBuffer.driverRenderDone == true) {
60682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // this is potential buffer for acquisition. Check if it is referenced by other surface for frame skipping
60782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VideoSurfaceBuffer *temp;
60882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            acquired = true;
60982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            for (int i = 0; i < mNumSurfaces; i++) {
61082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (i == nextAcquire) {
61182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    continue;
61282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
61382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                temp = mSurfaceBuffers + i;
61482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // use mSurfaces[nextAcquire] instead of acquiredBuffer->renderBuffer.surface as its the actual surface to use.
61582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (temp->renderBuffer.surface == mSurfaces[nextAcquire] &&
61682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    temp->renderBuffer.renderDone == false) {
61782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    ITRACE("Surface is referenced by other surface buffer.");
61882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    acquired = false;
61982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    break;
62082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
62182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
62282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
62382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (acquired) {
62482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
62582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
62682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        nextAcquire++;
62782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (nextAcquire == mNumSurfaces) {
62882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            nextAcquire = 0;
62982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
63082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (nextAcquire == mSurfaceAcquirePos) {
63182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_NO_SURFACE;
63282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
63382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
63482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
63582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (acquired == false) {
63682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_SURFACE;
63782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
63882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
63982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer = acquiredBuffer;
64082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceAcquirePos = nextAcquire;
64182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
64282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // set surface again as surface maybe reset by skipped frame.
64382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // skipped frame is a "non-coded frame" and decoder needs to duplicate the previous reference frame as the output.
64482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.surface = mSurfaces[mSurfaceAcquirePos];
64582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaceUserPtr && mAcquiredBuffer->mappedData) {
64682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->mappedData->data = mSurfaceUserPtr[mSurfaceAcquirePos];
64782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
64882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.timeStamp = INVALID_PTS;
64982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.display = mVADisplay;
65082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.flag = 0;
65182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.renderDone = false;
65282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->asReferernce = false;
65382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.errBuf.errorNumber = 0;
65482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.errBuf.timeStamp = INVALID_PTS;
65582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
65682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
65782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
65882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
65982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::outputSurfaceBuffer(void) {
66082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
66182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer == NULL) {
66282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
66382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
66482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
66582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
66682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mRawOutput) {
66782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = getRawDataFromSurface();
66882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS();
66982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
67082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
67182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // frame is successfly decoded to the current surface,  it is ready for output
67282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mShowFrame) {
67382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->renderBuffer.renderDone = false;
67482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
67582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->renderBuffer.renderDone = true;
67682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
67782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
67882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // decoder must set "asReference and referenceFrame" flags properly
67982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
68082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // update reference frames
68182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer->referenceFrame) {
68282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mManageReference) {
68382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // managing reference for MPEG4/H.263/WMV.
68482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // AVC should manage reference frame in a different way
68582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mForwardReference != NULL) {
68682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // this foward reference is no longer needed
68782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mForwardReference->asReferernce = false;
68882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
68982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // Forware reference for either P or B frame prediction
69082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mForwardReference = mLastReference;
69182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->asReferernce = true;
69282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
69382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
69482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // the last reference frame.
69582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mLastReference = mAcquiredBuffer;
69682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
69782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // add to the output list
69882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mShowFrame) {
69982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mOutputHead == NULL) {
70082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mOutputHead = mAcquiredBuffer;
70182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
70282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mOutputTail->next = mAcquiredBuffer;
70382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
70482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputTail = mAcquiredBuffer;
70582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputTail->next = NULL;
70682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
70782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
70882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //VTRACE("Pushing POC %d to queue (pts = %.2f)", mAcquiredBuffer->pictureOrder, mAcquiredBuffer->renderBuffer.timeStamp/1E6);
70982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
71082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer = NULL;
71182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceAcquirePos = (mSurfaceAcquirePos  + 1 ) % mNumSurfaces;
71282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
71382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
71482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
71582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::releaseSurfaceBuffer(void) {
71682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer == NULL) {
71782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // this is harmless error
71882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
71982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
72082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
72182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // frame is not decoded to the acquired buffer, current surface is invalid, and can't be output.
72282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->asReferernce = false;
72382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.renderDone = true;
72482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer = NULL;
72582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
72682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
72782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
72882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::flushSurfaceBuffers(void) {
72982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    endDecodingFrame(true);
73082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = NULL;
73182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    while (mOutputHead) {
73282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputHead->renderBuffer.renderDone = true;
73382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = mOutputHead;
73482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputHead = mOutputHead->next;
73582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p->next = NULL;
73682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
73782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mOutputHead = NULL;
73882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mOutputTail = NULL;
73982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
74082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
74182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::endDecodingFrame(bool dropFrame) {
74282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status = DECODE_SUCCESS;
74382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
74482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
74582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mDecodingFrame == false) {
74682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mAcquiredBuffer != NULL) {
74782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            //ETRACE("mAcquiredBuffer is not NULL. Implementation bug.");
74882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            releaseSurfaceBuffer();
74982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            status = DECODE_FAIL;
75082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
75182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return status;
75282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
75382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // return through exit label to reset mDecodingFrame
75482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer == NULL) {
75582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
75682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = DECODE_FAIL;
75782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        goto exit;
75882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
75982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
76082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaEndPicture(mVADisplay, mVAContext);
76182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (vaStatus != VA_STATUS_SUCCESS) {
76282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        releaseSurfaceBuffer();
76382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("vaEndPicture failed. vaStatus = %d", vaStatus);
76482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = DECODE_DRIVER_FAIL;
76582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        goto exit;
76682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
76782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
76882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (dropFrame) {
76982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // we are asked to drop this decoded picture
77082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VTRACE("Frame dropped in endDecodingFrame");
77182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaSyncSurface(mVADisplay, mAcquiredBuffer->renderBuffer.surface);
77282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        releaseSurfaceBuffer();
77382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        goto exit;
77482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
77582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = outputSurfaceBuffer();
77682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // fall through
77782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONexit:
77882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mDecodingFrame = false;
77982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return status;
78082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
78182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
78282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
78382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::setupVA(uint32_t numSurface, VAProfile profile, uint32_t numExtraSurface) {
78482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus = VA_STATUS_SUCCESS;
78582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
78682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
78782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted) {
78882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
78982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
79082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
79182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mRotationDegrees = 0;
79282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER){
793a6ebfeb41f53933b4a4882aab2b625b74204527dXigui Wang#ifdef TARGET_HAS_ISV
79482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber - mConfigBuffer.vppBufferNum)
79582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
79682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber)
79782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
79882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_FORMAT_CHANGE;
79982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
80082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        numSurface = mConfigBuffer.surfaceNumber;
80182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // if format has been changed in USE_NATIVE_GRAPHIC_BUFFER mode,
80282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // we can not setupVA here when the graphic buffer resolution is smaller than the resolution decoder really needs
80382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mSizeChanged) {
8041175ce579a69e847027026f615a053af76b792d5Tianmi Chen            if (mStoreMetaData || (!mStoreMetaData && (mVideoFormatInfo.surfaceWidth < mVideoFormatInfo.width || mVideoFormatInfo.surfaceHeight < mVideoFormatInfo.height))) {
80582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mSizeChanged = false;
80682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return DECODE_FORMAT_CHANGE;
80782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
80882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
80982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
81082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
81182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // TODO: validate profile
81282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (numSurface == 0) {
81382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
81482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
81582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
81682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConfigBuffer.flag & HAS_MINIMUM_SURFACE_NUMBER) {
81782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (numSurface < mConfigBuffer.surfaceNumber) {
81882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("surface to allocated %d is less than minimum number required %d",
81982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    numSurface, mConfigBuffer.surfaceNumber);
82082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            numSurface = mConfigBuffer.surfaceNumber;
82182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
82282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
82382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
82482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVADisplay != NULL) {
82582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("VA is partially started.");
82682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
82782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
82882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
82982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Display is defined as "unsigned int"
83082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_HYBRID_DRIVER
83182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mDisplay = new Display;
83282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    *mDisplay = ANDROID_DISPLAY_HANDLE;
83382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
83482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (profile >= VAProfileH264Baseline && profile <= VAProfileVC1Advanced) {
83582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("Using GEN driver");
83682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mDisplay = "libva_driver_name=i965";
83782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mUseGEN = true;
83882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
83982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("Using PVR driver");
84082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mDisplay = "libva_driver_name=pvr";
84182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mUseGEN = false;
84282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
84382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
84482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVADisplay = vaGetDisplay(mDisplay);
84582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVADisplay == NULL) {
84682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("vaGetDisplay failed.");
84782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_DRIVER_FAIL;
84882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
84982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
85082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int majorVersion, minorVersion;
85182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaInitialize(mVADisplay, &majorVersion, &minorVersion);
85282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaInitialize");
85382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
85482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((int32_t)profile != VAProfileSoftwareDecoding) {
85582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
85682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = checkHardwareCapability();
85782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("checkHardwareCapability");
85882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
85982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
86082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = getCodecSpecificConfigs(profile, &mVAConfig);
86182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("getCodecSpecificAttributes");
86282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
863661c5a76313015b6a3fea4b0e593b761a32f4372Andreas Gampe        VAConfigAttrib attrib;
86482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        //We are requesting RT attributes
86582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attrib.type = VAConfigAttribRTFormat;
86682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attrib.value = VA_RT_FORMAT_YUV420;
86782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
86882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateConfig(
86982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVADisplay,
87082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                profile,
87182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                VAEntrypointVLD,
87282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &attrib,
87382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                1,
87482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &mVAConfig);
87582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreateConfig");
87682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
87782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
87882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
87982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNumSurfaces = numSurface;
88082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNumExtraSurfaces = numExtraSurface;
88182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaces = new VASurfaceID [mNumSurfaces + mNumExtraSurfaces];
88282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mExtraSurfaces = mSurfaces + mNumSurfaces;
88368e939ffa64c34bef2272cfe6346f43ee84d1611Tianmi Chen    for (int i = 0; i < mNumSurfaces + mNumExtraSurfaces; ++i) {
88468e939ffa64c34bef2272cfe6346f43ee84d1611Tianmi Chen        mSurfaces[i] = VA_INVALID_SURFACE;
88568e939ffa64c34bef2272cfe6346f43ee84d1611Tianmi Chen    }
88682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaces == NULL) {
88782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_MEMORY_FAIL;
88882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
88982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
89082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    setRenderRect();
8919892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    setColorSpaceInfo(mVideoFormatInfo.colorMatrix, mVideoFormatInfo.videoRange);
89282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
89382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t format = VA_RT_FORMAT_YUV420;
89482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION) {
89582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_AVC_SHORT_FORMAT
89682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        format |= VA_RT_FORMAT_PROTECTED;
89782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("Surface is protected.");
89882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
89982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
90082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) {
9011175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (!mStoreMetaData) {
9021175ce579a69e847027026f615a053af76b792d5Tianmi Chen            VASurfaceAttrib attribs[2];
9031175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib = new VASurfaceAttribExternalBuffers;
9041175ce579a69e847027026f615a053af76b792d5Tianmi Chen            if (mVASurfaceAttrib == NULL) {
9051175ce579a69e847027026f615a053af76b792d5Tianmi Chen                return DECODE_MEMORY_FAIL;
9061175ce579a69e847027026f615a053af76b792d5Tianmi Chen            }
90782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9081175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->buffers= (unsigned long *)malloc(sizeof(unsigned long)*mNumSurfaces);
9091175ce579a69e847027026f615a053af76b792d5Tianmi Chen            if (mVASurfaceAttrib->buffers == NULL) {
9101175ce579a69e847027026f615a053af76b792d5Tianmi Chen                return DECODE_MEMORY_FAIL;
9111175ce579a69e847027026f615a053af76b792d5Tianmi Chen            }
9121175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->num_buffers = mNumSurfaces;
9131175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->pixel_format = VA_FOURCC_NV12;
9141175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->width = mVideoFormatInfo.surfaceWidth;
9151175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->height = mVideoFormatInfo.surfaceHeight;
916bb7b551f976e85040c4ddfb92100830c8c36d479Alistair Strachan            mVASurfaceAttrib->data_size = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride * 1.5;
9171175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->num_planes = 2;
918bb7b551f976e85040c4ddfb92100830c8c36d479Alistair Strachan            mVASurfaceAttrib->pitches[0] = mConfigBuffer.graphicBufferHStride;
919bb7b551f976e85040c4ddfb92100830c8c36d479Alistair Strachan            mVASurfaceAttrib->pitches[1] = mConfigBuffer.graphicBufferHStride;
9201175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->pitches[2] = 0;
9211175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->pitches[3] = 0;
9221175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->offsets[0] = 0;
923bb7b551f976e85040c4ddfb92100830c8c36d479Alistair Strachan            mVASurfaceAttrib->offsets[1] = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride;
9241175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->offsets[2] = 0;
9251175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->offsets[3] = 0;
9261175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->private_data = (void *)mConfigBuffer.nativeWindow;
9271175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVASurfaceAttrib->flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
9281175ce579a69e847027026f615a053af76b792d5Tianmi Chen            if (mConfigBuffer.flag & USE_TILING_MEMORY)
9291175ce579a69e847027026f615a053af76b792d5Tianmi Chen                mVASurfaceAttrib->flags |= VA_SURFACE_EXTBUF_DESC_ENABLE_TILING;
93082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9311175ce579a69e847027026f615a053af76b792d5Tianmi Chen            for (int i = 0; i < mNumSurfaces; i++) {
9321175ce579a69e847027026f615a053af76b792d5Tianmi Chen                mVASurfaceAttrib->buffers[i] = (unsigned long)mConfigBuffer.graphicBufferHandler[i];
9331175ce579a69e847027026f615a053af76b792d5Tianmi Chen            }
93482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9351175ce579a69e847027026f615a053af76b792d5Tianmi Chen            attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
9361175ce579a69e847027026f615a053af76b792d5Tianmi Chen            attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
9371175ce579a69e847027026f615a053af76b792d5Tianmi Chen            attribs[0].value.type = VAGenericValueTypeInteger;
9381175ce579a69e847027026f615a053af76b792d5Tianmi Chen            attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
93982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9401175ce579a69e847027026f615a053af76b792d5Tianmi Chen            attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
9411175ce579a69e847027026f615a053af76b792d5Tianmi Chen            attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
9421175ce579a69e847027026f615a053af76b792d5Tianmi Chen            attribs[1].value.type = VAGenericValueTypePointer;
9431175ce579a69e847027026f615a053af76b792d5Tianmi Chen            attribs[1].value.value.p = (void *)mVASurfaceAttrib;
94482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9451175ce579a69e847027026f615a053af76b792d5Tianmi Chen            vaStatus = vaCreateSurfaces(
9461175ce579a69e847027026f615a053af76b792d5Tianmi Chen                mVADisplay,
9471175ce579a69e847027026f615a053af76b792d5Tianmi Chen                format,
9481175ce579a69e847027026f615a053af76b792d5Tianmi Chen                mVideoFormatInfo.surfaceWidth,
9491175ce579a69e847027026f615a053af76b792d5Tianmi Chen                mVideoFormatInfo.surfaceHeight,
9501175ce579a69e847027026f615a053af76b792d5Tianmi Chen                mSurfaces,
9511175ce579a69e847027026f615a053af76b792d5Tianmi Chen                mNumSurfaces,
9521175ce579a69e847027026f615a053af76b792d5Tianmi Chen                attribs,
9531175ce579a69e847027026f615a053af76b792d5Tianmi Chen                2);
9541175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
95582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
95682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateSurfaces(
95782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
95882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            format,
95982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.width,
96082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.height,
96182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaces,
96282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mNumSurfaces,
96382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            NULL,
96482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            0);
96582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceWidth = mVideoFormatInfo.width;
96682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceHeight = mVideoFormatInfo.height;
96782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
96882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateSurfaces");
96982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
97082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mNumExtraSurfaces != 0) {
97182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateSurfaces(
97282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
97382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            format,
97482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.surfaceWidth,
97582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.surfaceHeight,
97682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExtraSurfaces,
97782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mNumExtraSurfaces,
97882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            NULL,
97982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            0);
98082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreateSurfaces");
98182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
98282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
98382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.surfaceNumber = mNumSurfaces;
98482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.ctxSurfaces = mSurfaces;
98582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
98682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((int32_t)profile != VAProfileSoftwareDecoding) {
9871175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (mStoreMetaData) {
9881175ce579a69e847027026f615a053af76b792d5Tianmi Chen            if (mUseGEN) {
9891175ce579a69e847027026f615a053af76b792d5Tianmi Chen                vaStatus = vaCreateContext(
9901175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    mVADisplay,
9911175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    mVAConfig,
9921175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    mVideoFormatInfo.surfaceWidth,
9931175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    mVideoFormatInfo.surfaceHeight,
9941175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    0,
9951175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    NULL,
9961175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    0,
9971175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    &mVAContext);
9981175ce579a69e847027026f615a053af76b792d5Tianmi Chen            } else {
9991175ce579a69e847027026f615a053af76b792d5Tianmi Chen                vaStatus = vaCreateContext(
10001175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    mVADisplay,
10011175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    mVAConfig,
10021175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    mVideoFormatInfo.surfaceWidth,
10031175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    mVideoFormatInfo.surfaceHeight,
10041175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    0,
10051175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    NULL,
10061175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    mNumSurfaces + mNumExtraSurfaces,
10071175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    &mVAContext);
10081175ce579a69e847027026f615a053af76b792d5Tianmi Chen            }
10091175ce579a69e847027026f615a053af76b792d5Tianmi Chen        } else {
10101175ce579a69e847027026f615a053af76b792d5Tianmi Chen            vaStatus = vaCreateContext(
101182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVADisplay,
101282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVAConfig,
101382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVideoFormatInfo.surfaceWidth,
101482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVideoFormatInfo.surfaceHeight,
101582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                0,
101682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mSurfaces,
101782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNumSurfaces + mNumExtraSurfaces,
101882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &mVAContext);
10191175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
102082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreateContext");
102182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
102282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
102382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceBuffers = new VideoSurfaceBuffer [mNumSurfaces];
102482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaceBuffers == NULL) {
102582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_MEMORY_FAIL;
102682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
102782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    initSurfaceBuffer(true);
102882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
102982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((int32_t)profile == VAProfileSoftwareDecoding) {
103082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // derive user pointer from surface for direct access
103182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = mapSurface();
103282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("mapSurface")
103382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
103482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
103582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    setRotationDegrees(mConfigBuffer.rotationDegrees);
103682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
103782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVAStarted = true;
10381175ce579a69e847027026f615a053af76b792d5Tianmi Chen
10391175ce579a69e847027026f615a053af76b792d5Tianmi Chen    pthread_mutex_lock(&mLock);
10401175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if (mStoreMetaData) {
10411175ce579a69e847027026f615a053af76b792d5Tianmi Chen        for (uint32_t i = 0; i < mMetaDataBuffersNum; i++) {
10421175ce579a69e847027026f615a053af76b792d5Tianmi Chen            status = createSurfaceFromHandle(i);
10431175ce579a69e847027026f615a053af76b792d5Tianmi Chen            CHECK_STATUS("createSurfaceFromHandle");
10441175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mSurfaceBuffers[i].renderBuffer.graphicBufferIndex = i;
10451175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
10461175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
10471175ce579a69e847027026f615a053af76b792d5Tianmi Chen    pthread_mutex_unlock(&mLock);
10481175ce579a69e847027026f615a053af76b792d5Tianmi Chen
104982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
105082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
105182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
105282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::terminateVA(void) {
105382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSignalBufferSize = 0;
105482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
105582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         mSignalBufferPre[i] = NULL;
105682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
105782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
105882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted == false) {
105982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // VA hasn't been started yet
106082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
106182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
106282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
106382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaceBuffers) {
106482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int32_t i = 0; i < mNumSurfaces; i++) {
106582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mSurfaceBuffers[i].renderBuffer.rawData) {
106682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (mSurfaceBuffers[i].renderBuffer.rawData->data) {
106782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    delete [] mSurfaceBuffers[i].renderBuffer.rawData->data;
106882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
106982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                delete mSurfaceBuffers[i].renderBuffer.rawData;
107082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
107182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mSurfaceBuffers[i].mappedData) {
107282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // don't  delete data pointer as it is mapped from surface
107382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                delete mSurfaceBuffers[i].mappedData;
107482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
107582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
107682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete [] mSurfaceBuffers;
107782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers = NULL;
107882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
107982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
108082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVASurfaceAttrib) {
108182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mVASurfaceAttrib->buffers) free(mVASurfaceAttrib->buffers);
108282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete mVASurfaceAttrib;
108382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib = NULL;
108482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
108582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
108682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
108782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaceUserPtr) {
108882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete [] mSurfaceUserPtr;
108982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceUserPtr = NULL;
109082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
109182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
109268e939ffa64c34bef2272cfe6346f43ee84d1611Tianmi Chen    if (mSurfaces) {
109368e939ffa64c34bef2272cfe6346f43ee84d1611Tianmi Chen        vaDestroySurfaces(mVADisplay, mSurfaces, mStoreMetaData ? mMetaDataBuffersNum : (mNumSurfaces + mNumExtraSurfaces));
109482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete [] mSurfaces;
109582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaces = NULL;
109682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
109782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
109882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAContext != VA_INVALID_ID) {
109982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         vaDestroyContext(mVADisplay, mVAContext);
110082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         mVAContext = VA_INVALID_ID;
110182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
110282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
110382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAConfig != VA_INVALID_ID) {
110482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaDestroyConfig(mVADisplay, mVAConfig);
110582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAConfig = VA_INVALID_ID;
110682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
110782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
110882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVADisplay) {
110982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaTerminate(mVADisplay);
111082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay = NULL;
111182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
111282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
111382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mDisplay) {
111482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_HYBRID_DRIVER
111582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete mDisplay;
111682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
111782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mDisplay = NULL;
111882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
111982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
112082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVAStarted = false;
112182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mInitialized = false;
112282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mErrReportEnabled = false;
11231175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if (mStoreMetaData) {
11241175ce579a69e847027026f615a053af76b792d5Tianmi Chen        mMetaDataBuffersNum = 0;
11251175ce579a69e847027026f615a053af76b792d5Tianmi Chen        mSurfaceAcquirePos = 0;
11261175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
112782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
112882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
112982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
113082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::parseBuffer(uint8_t *buffer, int32_t size, bool config, void** vbpData) {
113182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON     // DON'T check if mVAStarted == true
113282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle == NULL) {
113382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
113482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
113582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
113682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t vbpStatus;
113782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer == NULL || size <= 0) {
113882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
113982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
114082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
114182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint8_t configFlag = config ? 1 : 0;
114282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbpStatus = mParserParse(mParserHandle, buffer, size, configFlag);
114382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VBP_STATUS("vbp_parse");
114482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
114582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbpStatus = mParserQuery(mParserHandle, vbpData);
114682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VBP_STATUS("vbp_query");
114782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
114882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
114982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
115082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
115182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::mapSurface(void) {
115282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus = VA_STATUS_SUCCESS;
115382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAImage image;
115482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint8_t *userPtr;
115582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceUserPtr = new uint8_t* [mNumSurfaces];
115682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaceUserPtr == NULL) {
115782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_MEMORY_FAIL;
115882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
115982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
116082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i< mNumSurfaces; i++) {
116182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaDeriveImage(mVADisplay, mSurfaces[i], &image);
116282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaDeriveImage");
116382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaMapBuffer(mVADisplay, image.buf, (void**)&userPtr);
116482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaMapBuffer");
116582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceUserPtr[i] = userPtr;
116682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData = new VideoFrameRawData;
116782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mSurfaceBuffers[i].mappedData == NULL) {
116882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_MEMORY_FAIL;
116982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
117082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->own = false; // derived from surface so can't be released
117182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->data = NULL;  // specified during acquireSurfaceBuffer
117282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->fourcc = image.format.fourcc;
117382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->width = mVideoFormatInfo.width;
117482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->height = mVideoFormatInfo.height;
117582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->size = image.data_size;
117682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int pi = 0; pi < 3; pi++) {
117782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].mappedData->pitch[pi] = image.pitches[pi];
117882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].mappedData->offset[pi] = image.offsets[pi];
117982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
118082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // debug information
118182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (image.pitches[0] != image.pitches[1] ||
118282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            image.width != mVideoFormatInfo.width ||
118382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            image.height != mVideoFormatInfo.height ||
118482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            image.offsets[0] != 0) {
118582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("Unexpected VAImage format, w = %d, h = %d, offset = %d", image.width, image.height, image.offsets[0]);
118682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
118782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // TODO: do we need to unmap buffer?
118882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        //vaStatus = vaUnmapBuffer(mVADisplay, image.buf);
118982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        //CHECK_VA_STATUS("vaMapBuffer");
119082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaDestroyImage(mVADisplay,image.image_id);
119182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaDestroyImage");
119282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
119382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
119482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
119582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
119682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
119782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::getRawDataFromSurface(VideoRenderBuffer *renderBuffer, uint8_t *pRawData, uint32_t *pSize, bool internal) {
119882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (internal) {
119982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mAcquiredBuffer == NULL) {
120082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_FAIL;
120182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
120282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        renderBuffer = &(mAcquiredBuffer->renderBuffer);
120382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
120482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
120582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
120682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAImage vaImage;
120782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaSyncSurface(renderBuffer->display, renderBuffer->surface);
120882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaSyncSurface");
120982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
121082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaDeriveImage(renderBuffer->display, renderBuffer->surface, &vaImage);
121182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaDeriveImage");
121282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
121382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    void *pBuf = NULL;
121482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaMapBuffer(renderBuffer->display, vaImage.buf, &pBuf);
121582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaMapBuffer");
121682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
121782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
121882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // size in NV12 format
121982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t cropWidth = mVideoFormatInfo.width - (mVideoFormatInfo.cropLeft + mVideoFormatInfo.cropRight);
122082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t cropHeight = mVideoFormatInfo.height - (mVideoFormatInfo.cropBottom + mVideoFormatInfo.cropTop);
12213ed03d0de15f3910f40ee799cafc1d6a9b309e8dXin Wang    if (strcasecmp(mVideoFormatInfo.mimeType,"video/avc") == 0 ||
122242162bacfad5d5b6cd58dad8d2a1f810ded8ca88Austin Hu        strcasecmp(mVideoFormatInfo.mimeType,"video/avc-secure") == 0 ||
12233ed03d0de15f3910f40ee799cafc1d6a9b309e8dXin Wang        strcasecmp(mVideoFormatInfo.mimeType,"video/h264") == 0) {
12243ed03d0de15f3910f40ee799cafc1d6a9b309e8dXin Wang        cropHeight = mVideoFormatInfo.height;
12258008c14104b6acec387192a378aa6e976f4952ecXin Wang        cropWidth = mVideoFormatInfo.width;
12263ed03d0de15f3910f40ee799cafc1d6a9b309e8dXin Wang    }
122782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t size = cropWidth  * cropHeight * 3 / 2;
122882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
122982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (internal) {
123082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VideoFrameRawData *rawData = NULL;
123182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (renderBuffer->rawData == NULL) {
123282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            rawData = new VideoFrameRawData;
123382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (rawData == NULL) {
123482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return DECODE_MEMORY_FAIL;
123582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
123682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memset(rawData, 0, sizeof(VideoFrameRawData));
123782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            renderBuffer->rawData = rawData;
123882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
123982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            rawData = renderBuffer->rawData;
124082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
124182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
124282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (rawData->data != NULL && rawData->size != size) {
124382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            delete [] rawData->data;
124482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            rawData->data = NULL;
124582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            rawData->size = 0;
124682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
124782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (rawData->data == NULL) {
124882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            rawData->data = new uint8_t [size];
124982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (rawData->data == NULL) {
125082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return DECODE_MEMORY_FAIL;
125182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
125282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
125382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
125482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->own = true; // allocated by this library
125582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->width = cropWidth;
125682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->height = cropHeight;
125782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->pitch[0] = cropWidth;
125882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->pitch[1] = cropWidth;
125982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->pitch[2] = 0;  // interleaved U/V, two planes
126082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->offset[0] = 0;
126182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->offset[1] = cropWidth * cropHeight;
126282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->offset[2] = cropWidth * cropHeight * 3 / 2;
126382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->size = size;
126482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->fourcc = 'NV12';
126582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
126682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        pRawData = rawData->data;
126782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
126882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        *pSize = size;
126982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
127082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
127182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (size == (int32_t)vaImage.data_size) {
127282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifdef  __SSE4_1__
127382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        stream_memcpy(pRawData, pBuf, size);
127482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
127582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        memcpy(pRawData, pBuf, size);
127682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
127782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
127882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // copy Y data
127982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint8_t *src = (uint8_t*)pBuf;
128082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint8_t *dst = pRawData;
128182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint32_t row = 0;
128282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (row = 0; row < cropHeight; row++) {
128382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifdef  __SSE4_1__
128482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            stream_memcpy(dst, src, cropWidth);
128582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
128682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(dst, src, cropWidth);
128782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
128882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dst += cropWidth;
128982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            src += vaImage.pitches[0];
129082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
129182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // copy interleaved V and  U data
129282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        src = (uint8_t*)pBuf + vaImage.offsets[1];
129382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (row = 0; row < cropHeight / 2; row++) {
129482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifdef  __SSE4_1__
129582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            stream_memcpy(dst, src, cropWidth);
129682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
129782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(dst, src, cropWidth);
129882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
129982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dst += cropWidth;
130082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            src += vaImage.pitches[1];
130182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
130282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
130382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
130482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaUnmapBuffer(renderBuffer->display, vaImage.buf);
130582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaUnmapBuffer");
130682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
130782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaDestroyImage(renderBuffer->display, vaImage.image_id);
130882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaDestroyImage");
130982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
131082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
131182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
131282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
13131175ce579a69e847027026f615a053af76b792d5Tianmi ChenDecode_Status VideoDecoderBase::createSurfaceFromHandle(int index) {
13141175ce579a69e847027026f615a053af76b792d5Tianmi Chen    VAStatus vaStatus = VA_STATUS_SUCCESS;
13151175ce579a69e847027026f615a053af76b792d5Tianmi Chen    Decode_Status status;
13161175ce579a69e847027026f615a053af76b792d5Tianmi Chen
13171175ce579a69e847027026f615a053af76b792d5Tianmi Chen    int32_t format = VA_RT_FORMAT_YUV420;
13181175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION) {
13191175ce579a69e847027026f615a053af76b792d5Tianmi Chen#ifndef USE_AVC_SHORT_FORMAT
13201175ce579a69e847027026f615a053af76b792d5Tianmi Chen        format |= VA_RT_FORMAT_PROTECTED;
13211175ce579a69e847027026f615a053af76b792d5Tianmi Chen        WTRACE("Surface is protected.");
13221175ce579a69e847027026f615a053af76b792d5Tianmi Chen#endif
13231175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
13241175ce579a69e847027026f615a053af76b792d5Tianmi Chen    VASurfaceAttrib attribs[2];
13251175ce579a69e847027026f615a053af76b792d5Tianmi Chen    VASurfaceAttribExternalBuffers surfExtBuf;
13261175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.num_buffers = 1;
13271175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.pixel_format = VA_FOURCC_NV12;
13281175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.width = mVideoFormatInfo.surfaceWidth;
13291175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.height = mVideoFormatInfo.surfaceHeight;
1330bb7b551f976e85040c4ddfb92100830c8c36d479Alistair Strachan    surfExtBuf.data_size = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride * 1.5;
13311175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.num_planes = 2;
1332bb7b551f976e85040c4ddfb92100830c8c36d479Alistair Strachan    surfExtBuf.pitches[0] = mConfigBuffer.graphicBufferHStride;
1333bb7b551f976e85040c4ddfb92100830c8c36d479Alistair Strachan    surfExtBuf.pitches[1] = mConfigBuffer.graphicBufferHStride;
13341175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.pitches[2] = 0;
13351175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.pitches[3] = 0;
13361175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.offsets[0] = 0;
1337bb7b551f976e85040c4ddfb92100830c8c36d479Alistair Strachan    surfExtBuf.offsets[1] = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride;
13381175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.offsets[2] = 0;
13391175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.offsets[3] = 0;
13401175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.private_data = (void *)mConfigBuffer.nativeWindow;
13411175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
13421175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if (mConfigBuffer.flag & USE_TILING_MEMORY) {
13431175ce579a69e847027026f615a053af76b792d5Tianmi Chen        surfExtBuf.flags |= VA_SURFACE_EXTBUF_DESC_ENABLE_TILING;
13441175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
13451175ce579a69e847027026f615a053af76b792d5Tianmi Chen
13461175ce579a69e847027026f615a053af76b792d5Tianmi Chen    surfExtBuf.buffers = (long unsigned int*)&(mConfigBuffer.graphicBufferHandler[index]);
13471175ce579a69e847027026f615a053af76b792d5Tianmi Chen
13481175ce579a69e847027026f615a053af76b792d5Tianmi Chen    attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
13491175ce579a69e847027026f615a053af76b792d5Tianmi Chen    attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
13501175ce579a69e847027026f615a053af76b792d5Tianmi Chen    attribs[0].value.type = VAGenericValueTypeInteger;
13511175ce579a69e847027026f615a053af76b792d5Tianmi Chen    attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
13521175ce579a69e847027026f615a053af76b792d5Tianmi Chen
13531175ce579a69e847027026f615a053af76b792d5Tianmi Chen    attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
13541175ce579a69e847027026f615a053af76b792d5Tianmi Chen    attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
13551175ce579a69e847027026f615a053af76b792d5Tianmi Chen    attribs[1].value.type = VAGenericValueTypePointer;
13561175ce579a69e847027026f615a053af76b792d5Tianmi Chen    attribs[1].value.value.p = (void *)&surfExtBuf;
13571175ce579a69e847027026f615a053af76b792d5Tianmi Chen
13581175ce579a69e847027026f615a053af76b792d5Tianmi Chen    vaStatus = vaCreateSurfaces(
13591175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVADisplay,
13601175ce579a69e847027026f615a053af76b792d5Tianmi Chen            format,
13611175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVideoFormatInfo.surfaceWidth,
13621175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVideoFormatInfo.surfaceHeight,
13631175ce579a69e847027026f615a053af76b792d5Tianmi Chen            &(mSurfaces[index]),
13641175ce579a69e847027026f615a053af76b792d5Tianmi Chen            1,
13651175ce579a69e847027026f615a053af76b792d5Tianmi Chen            attribs,
13661175ce579a69e847027026f615a053af76b792d5Tianmi Chen        2);
13671175ce579a69e847027026f615a053af76b792d5Tianmi Chen    CHECK_VA_STATUS("vaCreateSurfaces");
13681175ce579a69e847027026f615a053af76b792d5Tianmi Chen
13691175ce579a69e847027026f615a053af76b792d5Tianmi Chen    return DECODE_SUCCESS;
13701175ce579a69e847027026f615a053af76b792d5Tianmi Chen}
13711175ce579a69e847027026f615a053af76b792d5Tianmi Chen
137282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::initSurfaceBuffer(bool reset) {
137382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
137482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (useGraphicBuffer && reset) {
137582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        pthread_mutex_lock(&mLock);
137682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
137782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < mNumSurfaces; i++) {
137882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.display = mVADisplay;
137982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.surface = VA_INVALID_SURFACE;  // set in acquireSurfaceBuffer
138082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.flag = 0;
138182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.scanFormat = VA_FRAME_PICTURE;
138282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.timeStamp = 0;
138382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].referenceFrame = false;
138482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].asReferernce= false;
138582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].pictureOrder = 0;
138682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].next = NULL;
138782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (reset == true) {
138882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].renderBuffer.rawData = NULL;
138982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].mappedData = NULL;
139082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
139182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (useGraphicBuffer) {
139282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (reset) {
139382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               mSurfaceBuffers[i].renderBuffer.graphicBufferHandle = mConfigBuffer.graphicBufferHandler[i];
139482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               mSurfaceBuffers[i].renderBuffer.renderDone = false; //default false
139582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               for (uint32_t j = 0; j < mSignalBufferSize; j++) {
139682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                   if(mSignalBufferPre[j] != NULL && mSignalBufferPre[j] == mSurfaceBuffers[i].renderBuffer.graphicBufferHandle) {
139782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                      mSurfaceBuffers[i].renderBuffer.renderDone = true;
139882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                      VTRACE("initSurfaceBuffer set renderDone = true index = %d", i);
139982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                      mSignalBufferPre[j] = NULL;
140082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                      break;
140182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                   }
140282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               }
140382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
140482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               mSurfaceBuffers[i].renderBuffer.renderDone = false;
140582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
140682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
140782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].renderBuffer.graphicBufferHandle = NULL;
140882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].renderBuffer.renderDone = true;
140982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
141082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.graphicBufferIndex = i;
141182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
141282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
141382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (useGraphicBuffer && reset) {
141482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mInitialized = true;
141582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSignalBufferSize = 0;
141682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        pthread_mutex_unlock(&mLock);
141782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
141882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
141982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14201175ce579a69e847027026f615a053af76b792d5Tianmi ChenDecode_Status VideoDecoderBase::signalRenderDone(void * graphichandler, bool isNew) {
14211175ce579a69e847027026f615a053af76b792d5Tianmi Chen    Decode_Status status;
142282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (graphichandler == NULL) {
142382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
142482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
142582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_lock(&mLock);
14261175ce579a69e847027026f615a053af76b792d5Tianmi Chen    bool graphicBufferMode = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
14271175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if (mStoreMetaData) {
14281175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (!graphicBufferMode) {
14291175ce579a69e847027026f615a053af76b792d5Tianmi Chen            pthread_mutex_unlock(&mLock);
14301175ce579a69e847027026f615a053af76b792d5Tianmi Chen            return DECODE_SUCCESS;
14311175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
14321175ce579a69e847027026f615a053af76b792d5Tianmi Chen
14331175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if ((mMetaDataBuffersNum < mConfigBuffer.surfaceNumber) && isNew) {
14341175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mConfigBuffer.graphicBufferHandler[mMetaDataBuffersNum] = graphichandler;
14351175ce579a69e847027026f615a053af76b792d5Tianmi Chen            if (mInitialized) {
14361175ce579a69e847027026f615a053af76b792d5Tianmi Chen                mSurfaceBuffers[mMetaDataBuffersNum].renderBuffer.graphicBufferHandle = graphichandler;
14371175ce579a69e847027026f615a053af76b792d5Tianmi Chen                mSurfaceBuffers[mMetaDataBuffersNum].renderBuffer.graphicBufferIndex = mMetaDataBuffersNum;
14381175ce579a69e847027026f615a053af76b792d5Tianmi Chen            }
14391175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
14401175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
144182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int i = 0;
144282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mInitialized) {
144382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mSignalBufferSize >= MAX_GRAPHIC_BUFFER_NUM) {
144482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            pthread_mutex_unlock(&mLock);
144582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_INVALID_DATA;
144682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
144782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSignalBufferPre[mSignalBufferSize++] = graphichandler;
144882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VTRACE("SignalRenderDoneFlag mInitialized = false graphichandler = %p, mSignalBufferSize = %d", graphichandler, mSignalBufferSize);
144982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
14501175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (!graphicBufferMode) {
145182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            pthread_mutex_unlock(&mLock);
145282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_SUCCESS;
145382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
14541175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (mStoreMetaData) {
14551175ce579a69e847027026f615a053af76b792d5Tianmi Chen            if ((mMetaDataBuffersNum < mConfigBuffer.surfaceNumber) && isNew) {
14561175ce579a69e847027026f615a053af76b792d5Tianmi Chen                if (mVAStarted) {
14571175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    status = createSurfaceFromHandle(mMetaDataBuffersNum);
14581175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    CHECK_STATUS("createSurfaceFromHandle")
14591175ce579a69e847027026f615a053af76b792d5Tianmi Chen                }
14601175ce579a69e847027026f615a053af76b792d5Tianmi Chen            }
14611175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
146282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (i = 0; i < mNumSurfaces; i++) {
146382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mSurfaceBuffers[i].renderBuffer.graphicBufferHandle == graphichandler) {
146482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mSurfaceBuffers[i].renderBuffer.renderDone = true;
146582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                VTRACE("SignalRenderDoneFlag mInitialized = true index = %d", i);
146682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               break;
146782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON           }
146882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
146982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
14701175ce579a69e847027026f615a053af76b792d5Tianmi Chen
14711175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if (mStoreMetaData) {
14721175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if ((mMetaDataBuffersNum < mConfigBuffer.surfaceNumber) && isNew) {
14731175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mMetaDataBuffersNum++;
14741175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
14751175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
14761175ce579a69e847027026f615a053af76b792d5Tianmi Chen
147782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_unlock(&mLock);
147882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
147982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
148082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
148182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
148282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
148382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::querySurfaceRenderStatus(VideoSurfaceBuffer* surface) {
148482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VASurfaceStatus surfStat = VASurfaceReady;
148582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus    vaStat = VA_STATUS_SUCCESS;
148682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
148782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!surface) {
148882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOGW("SurfaceBuffer not ready yet");
148982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return;
149082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
149182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    surface->renderBuffer.driverRenderDone = true;
149282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
149382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_GEN_HW
149482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (surface->renderBuffer.surface != VA_INVALID_SURFACE &&
149582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON       (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) {
149682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
149782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStat = vaQuerySurfaceStatus(mVADisplay, surface->renderBuffer.surface, &surfStat);
149882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
149982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if ((vaStat == VA_STATUS_SUCCESS) && (surfStat != VASurfaceReady))
150082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            surface->renderBuffer.driverRenderDone = false;
150182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
150282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
150382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
150482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
150582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
150682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
150782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON// This function should be called before start() to load different type of parsers
150882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
150982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::setParserType(_vbp_parser_type type) {
151082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((int32_t)type != VBP_INVALID) {
151182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("Parser Type = %d", (int32_t)type);
151282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mParserType = type;
151382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
151482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
151582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Invalid parser type = %d", (int32_t)type);
151682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
151782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
151882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
151982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
152082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::updateBuffer(uint8_t *buffer, int32_t size, void** vbpData) {
152182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle == NULL) {
152282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
152382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
152482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
152582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t vbpStatus;
152682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer == NULL || size <= 0) {
152782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
152882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
152982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
153082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbpStatus = mParserUpdate(mParserHandle, buffer, size, vbpData);
153182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VBP_STATUS("vbp_update");
153282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
153382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
153482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
153582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
153682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::queryBuffer(void** vbpData) {
153782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle == NULL) {
153882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
153982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
154082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
154182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t vbpStatus;
154282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbpStatus = mParserQuery(mParserHandle, vbpData);
154382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VBP_STATUS("vbp_query");
154482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
154582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
154682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
154782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
154882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::getCodecSpecificConfigs(VAProfile profile, VAConfigID *config) {
154982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
155082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAConfigAttrib attrib;
155182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib.type = VAConfigAttribRTFormat;
155282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib.value = VA_RT_FORMAT_YUV420;
155382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
155482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (config == NULL) {
155582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Invalid parameter!");
155682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
155782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
155882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
155982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateConfig(
156082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
156182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            profile,
156282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAEntrypointVLD,
156382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &attrib,
156482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            1,
156582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            config);
156682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
156782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateConfig");
156882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
156982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
157082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
157182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
157282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::checkHardwareCapability() {
157382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
157482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
157582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
157682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::drainDecodingErrors(VideoErrorBuffer *outErrBuf, VideoRenderBuffer *currentSurface) {
157782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mErrReportEnabled && outErrBuf && currentSurface) {
157882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        memcpy(outErrBuf, &(currentSurface->errBuf), sizeof(VideoErrorBuffer));
157982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
158082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        currentSurface->errBuf.errorNumber = 0;
158182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        currentSurface->errBuf.timeStamp = INVALID_PTS;
158282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
158382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (outErrBuf)
158482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VTRACE("%s: error number is %d", __FUNCTION__, outErrBuf->errorNumber);
158582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
158682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
158782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::fillDecodingErrors(VideoRenderBuffer *currentSurface) {
158882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus ret;
158982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
159082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mErrReportEnabled) {
159182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        currentSurface->errBuf.timeStamp = currentSurface->timeStamp;
159282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // TODO: is 10 a suitable number?
159382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VASurfaceDecodeMBErrors *err_drv_output = NULL;
159482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ret = vaQuerySurfaceError(mVADisplay, currentSurface->surface, VA_STATUS_ERROR_DECODING_ERROR, (void **)&err_drv_output);
159582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (ret || !err_drv_output) {
159682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("vaQuerySurfaceError failed.");
159782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return;
159882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
159982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
160082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int offset =  0x1 & currentSurface->errBuf.errorNumber;// offset is either 0 or 1
160182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int i = 0; i < MAX_ERR_NUM - offset; i++) {
160282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (err_drv_output[i].status != -1) {
160382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                currentSurface->errBuf.errorNumber++;
160482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                currentSurface->errBuf.errorArray[i + offset].type = DecodeMBError;
160582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.start_mb = err_drv_output[i].start_mb;
160682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.end_mb = err_drv_output[i].end_mb;
160782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                currentSurface->errBuf.errorArray[i + offset].num_mbs = err_drv_output[i].end_mb - err_drv_output[i].start_mb + 1;
160882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                ITRACE("Error Index[%d]: type = %d, start_mb = %d, end_mb = %d",
160982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    currentSurface->errBuf.errorNumber - 1,
161082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    currentSurface->errBuf.errorArray[i + offset].type,
161182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.start_mb,
161282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.end_mb);
161382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else break;
161482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
161582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("%s: error number of current surface is %d, timestamp @%llu",
161682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            __FUNCTION__, currentSurface->errBuf.errorNumber, currentSurface->timeStamp);
161782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
161882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
161982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
162082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::setRotationDegrees(int32_t rotationDegrees) {
162182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mRotationDegrees == rotationDegrees) {
162282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return;
162382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
162482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
162582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ITRACE("set new rotation degree: %d", rotationDegrees);
162682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VADisplayAttribute rotate;
162782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rotate.type = VADisplayAttribRotation;
162882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rotate.value = VA_ROTATION_NONE;
162982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (rotationDegrees == 0)
163082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rotate.value = VA_ROTATION_NONE;
163182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    else if (rotationDegrees == 90)
163282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rotate.value = VA_ROTATION_90;
163382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    else if (rotationDegrees == 180)
163482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rotate.value = VA_ROTATION_180;
163582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    else if (rotationDegrees == 270)
163682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rotate.value = VA_ROTATION_270;
163782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
163882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus ret = vaSetDisplayAttributes(mVADisplay, &rotate, 1);
163982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (ret) {
164082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Failed to set rotation degree.");
164182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
164282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mRotationDegrees = rotationDegrees;
164382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
164482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
164582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::setRenderRect() {
164682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
164782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mVADisplay)
164882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return;
164982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
165082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus ret;
165182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VARectangle rect;
165282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rect.x = mVideoFormatInfo.cropLeft;
165382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rect.y = mVideoFormatInfo.cropTop;
165482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rect.width = mVideoFormatInfo.width - (mVideoFormatInfo.cropLeft + mVideoFormatInfo.cropRight);
165582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rect.height = mVideoFormatInfo.height - (mVideoFormatInfo.cropBottom + mVideoFormatInfo.cropTop);
16563ed03d0de15f3910f40ee799cafc1d6a9b309e8dXin Wang    if (strcasecmp(mVideoFormatInfo.mimeType,"video/avc") == 0 ||
165742162bacfad5d5b6cd58dad8d2a1f810ded8ca88Austin Hu        strcasecmp(mVideoFormatInfo.mimeType,"video/avc-secure") == 0 ||
16583ed03d0de15f3910f40ee799cafc1d6a9b309e8dXin Wang        strcasecmp(mVideoFormatInfo.mimeType,"video/h264") == 0) {
16593ed03d0de15f3910f40ee799cafc1d6a9b309e8dXin Wang        rect.height = mVideoFormatInfo.height;
16608008c14104b6acec387192a378aa6e976f4952ecXin Wang        rect.width = mVideoFormatInfo.width;
16613ed03d0de15f3910f40ee799cafc1d6a9b309e8dXin Wang    }
166282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
166382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VADisplayAttribute render_rect;
166482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    render_rect.type = VADisplayAttribRenderRect;
16659892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    render_rect.attrib_ptr = &rect;
166682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
166782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ret = vaSetDisplayAttributes(mVADisplay, &render_rect, 1);
166882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (ret) {
166982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Failed to set rotation degree.");
167082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
167182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
16729892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding
16739892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Dingvoid VideoDecoderBase::setColorSpaceInfo(int32_t colorMatrix, int32_t videoRange) {
16749892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    ITRACE("set colorMatrix: 0x%x ", colorMatrix);
16759892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    VADisplayAttribute cm;
16769892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    cm.type = VADisplayAttribCSCMatrix;
16779892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    if (colorMatrix == VA_SRC_BT601) {
16789892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding        cm.attrib_ptr = &s601;
16799892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    } else if (colorMatrix == VA_SRC_BT709) {
16809892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding        cm.attrib_ptr = &s709;
16819892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    } else {
16829892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding      // if we can't get the color matrix or it's not BT601 or BT709
16839892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding      // we decide the color matrix according to clip resolution
16849892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding      if (mVideoFormatInfo.width < 1280 && mVideoFormatInfo.height < 720)
16859892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding          cm.attrib_ptr = &s601;
16869892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding      else
16879892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding          cm.attrib_ptr = &s709;
16889892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    }
16899892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding
16909892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    VAStatus ret = vaSetDisplayAttributes(mVADisplay, &cm, 1);
16919892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding
16929892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    if (ret) {
16939892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding        ETRACE("Failed to set colorMatrix.");
16949892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    }
16959892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding
16969892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    // 1: full range, 0: reduced range
16979892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    ITRACE("set videoRange: %d ", videoRange);
16989892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    VADisplayAttribute vr;
16999892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    vr.type = VADisplayAttribColorRange;
17009892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    vr.value = (videoRange == 1) ? VA_SOURCE_RANGE_FULL : VA_SOURCE_RANGE_REDUCED;
17019892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding
17029892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    ret = vaSetDisplayAttributes(mVADisplay, &vr, 1);
17039892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding
17049892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    if (ret) {
17059892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding        ETRACE("Failed to set videoRange.");
17069892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    }
17079892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding}
1708