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),
3482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mDisplay(NULL),
3582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVADisplay(NULL),
3682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVAContext(VA_INVALID_ID),
3782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVAConfig(VA_INVALID_ID),
3882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVAStarted(false),
3982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mCurrentPTS(INVALID_PTS),
4082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mAcquiredBuffer(NULL),
4182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mLastReference(NULL),
4282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mForwardReference(NULL),
4382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mDecodingFrame(false),
4482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSizeChanged(false),
4582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mShowFrame(true),
4682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mOutputWindowSize(OUTPUT_WINDOW_SIZE),
4782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mRotationDegrees(0),
4882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mErrReportEnabled(false),
4982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mWiDiOn(false),
5082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mRawOutput(false),
5182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mManageReference(true),
5282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mOutputMethod(OUTPUT_BY_PCT),
5382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mNumSurfaces(0),
5482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSurfaceBuffers(NULL),
5582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mOutputHead(NULL),
5682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mOutputTail(NULL),
5782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSurfaces(NULL),
5882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVASurfaceAttrib(NULL),
5982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSurfaceUserPtr(NULL),
6082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSurfaceAcquirePos(0),
6182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mNextOutputPOC(MINIMUM_POC),
6282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mParserType(type),
6382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mParserHandle(NULL),
6482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSignalBufferSize(0) {
6582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memset(&mVideoFormatInfo, 0, sizeof(VideoFormatInfo));
6782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memset(&mConfigBuffer, 0, sizeof(mConfigBuffer));
6882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
6982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         mSignalBufferPre[i] = NULL;
7082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
7182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_init(&mLock, NULL);
7282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.mimeType = strdup(mimeType);
7382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mUseGEN = false;
7482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLibHandle = NULL;
7582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserOpen = NULL;
7682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserClose = NULL;
7782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserParse = NULL;
7882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserQuery = NULL;
7982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserFlush = NULL;
8082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserUpdate = NULL;
8182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
8282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderBase::~VideoDecoderBase() {
8482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_destroy(&mLock);
8582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    stop();
8682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    free(mVideoFormatInfo.mimeType);
8782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
8882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::start(VideoConfigBuffer *buffer) {
9082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer == NULL) {
9182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
9282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
9382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle != NULL) {
9582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("Decoder has already started.");
9682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
9782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
9882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLibHandle = dlopen("libmixvbp.so", RTLD_NOW);
9982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mLibHandle == NULL) {
10082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON       return DECODE_NO_PARSER;
10182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
10282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserOpen = (OpenFunc)dlsym(mLibHandle, "vbp_open");
10382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserClose = (CloseFunc)dlsym(mLibHandle, "vbp_close");
10482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserParse = (ParseFunc)dlsym(mLibHandle, "vbp_parse");
10582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserQuery = (QueryFunc)dlsym(mLibHandle, "vbp_query");
10682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserFlush = (FlushFunc)dlsym(mLibHandle, "vbp_flush");
10782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserOpen == NULL || mParserClose == NULL || mParserParse == NULL
10882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        || mParserQuery == NULL || mParserFlush == NULL) {
10982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
11082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
11182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
11282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mParserUpdate = (UpdateFunc)dlsym(mLibHandle, "vbp_update");
11382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserUpdate == NULL) {
11482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
11582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
11682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
11782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((int32_t)mParserType != VBP_INVALID) {
11882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("mParserType = %d", mParserType);
11982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mParserOpen(mParserType, &mParserHandle) != VBP_OK) {
12082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ETRACE("Failed to open VBP parser.");
12182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_NO_PARSER;
12282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
12382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
12482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // keep a copy of configure buffer, meta data only. It can be used to override VA setup parameter.
12582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer = *buffer;
12682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer.data = NULL;
12782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer.size = 0;
12882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
12982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.width = buffer->width;
13082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.height = buffer->height;
13182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) {
13282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceWidth = buffer->graphicBufferWidth;
13382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceHeight = buffer->graphicBufferHeight;
13482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
13582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLowDelay = buffer->flag & WANT_LOW_DELAY;
13682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mRawOutput = buffer->flag & WANT_RAW_OUTPUT;
13782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mRawOutput) {
13882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("Output is raw data.");
13982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
14082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
14282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
14382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::reset(VideoConfigBuffer *buffer) {
14682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer == NULL) {
14782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
14882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
14982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // if VA is already started, terminate VA as graphic buffers are reallocated by omxcodec
15182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    terminateVA();
15282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // reset the mconfigBuffer to pass it for startVA.
15482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer = *buffer;
15582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer.data = NULL;
15682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConfigBuffer.size = 0;
15782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.width = buffer->width;
15982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.height = buffer->height;
16082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) {
16182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceWidth = buffer->graphicBufferWidth;
16282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceHeight = buffer->graphicBufferHeight;
16382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
16482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.actualBufferNeeded = mConfigBuffer.surfaceNumber;
16582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLowDelay = buffer->flag & WANT_LOW_DELAY;
16682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mRawOutput = buffer->flag & WANT_RAW_OUTPUT;
16782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mRawOutput) {
16882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("Output is raw data.");
16982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
17082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
17182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
17282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
17382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
17482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
17582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::stop(void) {
17682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    terminateVA();
17782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
17882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mCurrentPTS = INVALID_PTS;
17982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer = NULL;
18082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastReference = NULL;
18182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mForwardReference = NULL;
18282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mDecodingFrame = false;
18382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSizeChanged = false;
18482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // private variables
18682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLowDelay = false;
18782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mRawOutput = false;
18882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNumSurfaces = 0;
18982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceAcquirePos = 0;
19082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNextOutputPOC = MINIMUM_POC;
19182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.valid = false;
19282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle){
19382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mParserClose(mParserHandle);
19482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mParserHandle = NULL;
19582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
19682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mLibHandle) {
19782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dlclose(mLibHandle);
19882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mLibHandle = NULL;
19982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
20082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
20182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
20282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::flush(void) {
20382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted == false) {
20482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // nothing to flush at this stage
20582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return;
20682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
20782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
20882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    endDecodingFrame(true);
20982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = mOutputHead;
21182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // check if there's buffer with DRC flag in the output queue
21282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    while (p) {
21382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->renderBuffer.flag & IS_RESOLUTION_CHANGE) {
21482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSizeChanged = true;
21582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
21682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
21782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
21882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
21982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // avoid setting mSurfaceAcquirePos  to 0 as it may cause tearing
22082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // (surface is still being rendered)
22182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceAcquirePos = (mSurfaceAcquirePos  + 1) % mNumSurfaces;
22282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNextOutputPOC = MINIMUM_POC;
22382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mCurrentPTS = INVALID_PTS;
22482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer = NULL;
22582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastReference = NULL;
22682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mForwardReference = NULL;
22782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mOutputHead = NULL;
22882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mOutputTail = NULL;
22982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mDecodingFrame = false;
23082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // flush vbp parser
23282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle && (mParserFlush(mParserHandle) != VBP_OK)) {
23382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("Failed to flush parser. Continue");
23482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
23582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // initialize surface buffer without resetting mapped/raw data
23782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    initSurfaceBuffer(false);
23882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
24082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::freeSurfaceBuffers(void) {
24282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted == false) {
24382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // nothing to free surface buffers at this stage
24482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return;
24582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
24682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_lock(&mLock);
24882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    endDecodingFrame(true);
25082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // if VA is already started, terminate VA as graphic buffers are reallocated by omxcodec
25282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    terminateVA();
25382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_unlock(&mLock);
25582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
25682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONconst VideoFormatInfo* VideoDecoderBase::getFormatInfo(void) {
25882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return &mVideoFormatInfo;
25982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
26082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONconst VideoRenderBuffer* VideoDecoderBase::getOutput(bool draining, VideoErrorBuffer *outErrBuf) {
26282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
26382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted == false) {
26482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return NULL;
26582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
26682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
26782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (draining) {
26982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // complete decoding the last frame and ignore return
27082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        endDecodingFrame(false);
27182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
27282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
27382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mOutputHead == NULL) {
27482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return NULL;
27582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
27682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
27782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output by position (the first buffer)
27882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputByPos = mOutputHead;
27982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
28082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mLowDelay) {
28182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputHead = mOutputHead->next;
28282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mOutputHead == NULL) {
28382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mOutputTail = NULL;
28482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
28582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaSetTimestampForSurface(mVADisplay, outputByPos->renderBuffer.surface, outputByPos->renderBuffer.timeStamp);
28682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (useGraphicBuffer && !mUseGEN) {
28782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            vaSyncSurface(mVADisplay, outputByPos->renderBuffer.surface);
28882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            fillDecodingErrors(&(outputByPos->renderBuffer));
28982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
29082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (draining && mOutputTail == NULL) {
29182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outputByPos->renderBuffer.flag |= IS_EOS;
29282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
29382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        drainDecodingErrors(outErrBuf, &(outputByPos->renderBuffer));
29482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
29582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return &(outputByPos->renderBuffer);
29682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
29782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
29882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output by presentation time stamp (the smallest pts)
29982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputByPts = findOutputByPts();
30082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
30182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *output = NULL;
30282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mOutputMethod == OUTPUT_BY_POC) {
30382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        output = findOutputByPoc(draining);
30482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else if (mOutputMethod == OUTPUT_BY_PCT) {
30582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        output = findOutputByPct(draining);
30682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
30782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Invalid output method.");
30882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return NULL;
30982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
31082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (output == NULL) {
31282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return NULL;
31382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
31482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (output != outputByPts) {
31682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // swap time stamp
31782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint64_t ts = output->renderBuffer.timeStamp;
31882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        output->renderBuffer.timeStamp = outputByPts->renderBuffer.timeStamp;
31982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        outputByPts->renderBuffer.timeStamp = ts;
32082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
32182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (output != outputByPos) {
32382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // remove this output from middle or end of the list
32482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VideoSurfaceBuffer *p = outputByPos;
32582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        while (p->next != output) {
32682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            p = p->next;
32782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
32882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p->next = output->next;
32982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mOutputTail == output) {
33082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mOutputTail = p;
33182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
33282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
33382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // remove this output from head of the list
33482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputHead = mOutputHead->next;
33582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mOutputHead == NULL) {
33682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mOutputTail = NULL;
33782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
33882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
33982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //VTRACE("Output POC %d for display (pts = %.2f)", output->pictureOrder, output->renderBuffer.timeStamp/1E6);
34082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaSetTimestampForSurface(mVADisplay, output->renderBuffer.surface, output->renderBuffer.timeStamp);
34182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
34282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (useGraphicBuffer && !mUseGEN) {
34382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaSyncSurface(mVADisplay, output->renderBuffer.surface);
34482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        fillDecodingErrors(&(output->renderBuffer));
34582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
34682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
34782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (draining && mOutputTail == NULL) {
34882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        output->renderBuffer.flag |= IS_EOS;
34982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
35082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
35182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    drainDecodingErrors(outErrBuf, &(output->renderBuffer));
35282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
35382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return &(output->renderBuffer);
35482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
35582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
35682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoSurfaceBuffer* VideoDecoderBase::findOutputByPts() {
35782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output by presentation time stamp - buffer with the smallest time stamp is output
35882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = mOutputHead;
35982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputByPts = NULL;
36082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint64_t pts = INVALID_PTS;
36182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    do {
36282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if ((uint64_t)(p->renderBuffer.timeStamp) <= pts) {
36382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // find buffer with the smallest PTS
36482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            pts = p->renderBuffer.timeStamp;
36582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outputByPts = p;
36682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
36782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
36882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } while (p != NULL);
36982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
37082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return outputByPts;
37182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
37282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
37382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoSurfaceBuffer* VideoDecoderBase::findOutputByPct(bool draining) {
37482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output by picture coding type (PCT)
37582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // if there is more than one reference frame, the first reference frame is ouput, otherwise,
37682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output non-reference frame if there is any.
37782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
37882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = mOutputHead;
37982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputByPct = NULL;
38082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t reference = 0;
38182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    do {
38282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->referenceFrame) {
38382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            reference++;
38482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (reference > 1) {
38582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // mOutputHead must be a reference frame
38682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                outputByPct = mOutputHead;
38782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                break;
38882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
38982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
39082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // first non-reference frame
39182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outputByPct = p;
39282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
39382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
39482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
39582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } while (p != NULL);
39682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
39782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (outputByPct == NULL && draining) {
39882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        outputByPct = mOutputHead;
39982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
40082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return  outputByPct;
40182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
40282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
40382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if 0
40482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoSurfaceBuffer* VideoDecoderBase::findOutputByPoc(bool draining) {
40582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output by picture order count (POC)
40682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Output criteria:
40782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // if there is IDR frame (POC == 0), all the frames before IDR must be output;
40882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Otherwise, if draining flag is set or list is full, frame with the least POC is output;
40982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Otherwise, NOTHING is output
41082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
41182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t dpbFullness = 0;
41282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < mNumSurfaces; i++) {
41382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // count num of reference frames
41482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mSurfaceBuffers[i].asReferernce) {
41582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dpbFullness++;
41682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
41782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
41882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
41982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer && mAcquiredBuffer->asReferernce) {
42082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // frame is being decoded and is not ready for output yet
42182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dpbFullness--;
42282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
42382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
42482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = mOutputHead;
42582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    while (p != NULL) {
42682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // count dpbFullness with non-reference frame in the output queue
42782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->asReferernce == false) {
42882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dpbFullness++;
42982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
43082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
43182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
43282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
43382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONRetry:
43482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    p = mOutputHead;
43582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputByPoc = NULL;
43682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t count = 0;
43782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t poc = MAXIMUM_POC;
43882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
43982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    do {
44082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->pictureOrder == 0) {
44182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // output picture with the least POC before IDR
44282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (outputByPoc != NULL) {
44382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = outputByPoc->pictureOrder + 1;
44482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return outputByPoc;
44582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
44682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = MINIMUM_POC;
44782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
44882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
44982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // POC of  the output candidate must not be less than mNextOutputPOC
45182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->pictureOrder < mNextOutputPOC) {
45282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
45382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
45482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->pictureOrder < poc) {
45682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // update the least POC.
45782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            poc = p->pictureOrder;
45882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outputByPoc = p;
45982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
46082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        count++;
46182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
46282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } while (p != NULL && count < mOutputWindowSize);
46382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
46482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (draining == false && dpbFullness < mOutputWindowSize) {
46582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // list is not  full and we are not  in draining state
46682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // if DPB is already full, one frame must be output
46782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return NULL;
46882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
46982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
47082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (outputByPoc == NULL) {
47182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mNextOutputPOC = MINIMUM_POC;
47282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        goto Retry;
47382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
47482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
47582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // for debugging purpose
47682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (outputByPoc->pictureOrder != 0 && outputByPoc->pictureOrder < mNextOutputPOC) {
47782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Output POC is not incremental, expected %d, actual %d", mNextOutputPOC, outputByPoc->pictureOrder);
47882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        //gaps_in_frame_num_value_allowed_flag is not currently supported
47982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
48082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
48182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNextOutputPOC = outputByPoc->pictureOrder + 1;
48282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
48382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return outputByPoc;
48482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
48582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
48682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoSurfaceBuffer* VideoDecoderBase::findOutputByPoc(bool draining) {
48782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *output = NULL;
48882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = mOutputHead;
48982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t count = 0;
49082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t poc = MAXIMUM_POC;
49182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *outputleastpoc = mOutputHead;
49282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    do {
49382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        count++;
49482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->pictureOrder == 0) {
49582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // any picture before this POC (new IDR) must be output
49682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (output == NULL) {
49782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = MINIMUM_POC;
49882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // looking for any POC with negative value
49982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
50082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = output->pictureOrder + 1;
50182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                break;
50282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
50382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
50482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->pictureOrder < poc && p->pictureOrder >= mNextOutputPOC) {
50582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // this POC meets ouput criteria.
50682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            poc = p->pictureOrder;
50782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            output = p;
50882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outputleastpoc = p;
50982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
51082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (poc == mNextOutputPOC || count == mOutputWindowSize) {
51182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (output != NULL) {
51282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // this indicates two cases:
51382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // 1) the next output POC is found.
51482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // 2) output queue is full and there is at least one buffer meeting the output criteria.
51582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = output->pictureOrder + 1;
51682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                break;
51782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
51882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // this indicates output queue is full and no buffer in the queue meets the output criteria
51982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // restart processing as queue is FULL and output criteria is changed. (next output POC is 0)
52082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNextOutputPOC = MINIMUM_POC;
52182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                count = 0;
52282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                poc = MAXIMUM_POC;
52382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                p = mOutputHead;
52482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                continue;
52582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
52682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
52782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->next == NULL) {
52882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            output = NULL;
52982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
53082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
53182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = p->next;
53282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } while (p != NULL);
53382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
53482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (draining == true && output == NULL) {
53582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        output = outputleastpoc;
53682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
53782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
53882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return output;
53982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
54082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
54182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
54282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONbool VideoDecoderBase::checkBufferAvail(void) {
54382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mInitialized) {
54482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) == 0) {
54582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return true;
54682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
54782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
54882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mSignalBufferPre[i] != NULL) {
54982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return true;
55082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
55182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
55282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return false;
55382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
55482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // check whether there is buffer available for decoding
55582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // TODO: check frame being referenced for frame skipping
55682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *buffer = NULL;
55782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < mNumSurfaces; i++) {
55882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        buffer = mSurfaceBuffers + i;
55982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
56082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (buffer->asReferernce == false &&
56182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            buffer->renderBuffer.renderDone == true) {
56282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            querySurfaceRenderStatus(buffer);
56382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (buffer->renderBuffer.driverRenderDone == true)
56482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return true;
56582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
56682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON     }
56782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return false;
56882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
56982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
57082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::acquireSurfaceBuffer(void) {
57182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted == false) {
57282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
57382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
57482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
57582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer != NULL) {
57682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("mAcquiredBuffer is not NULL. Implementation bug.");
57782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
57882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
57982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
58082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int nextAcquire = mSurfaceAcquirePos;
58182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *acquiredBuffer = NULL;
58282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool acquired = false;
58382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
58482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    while (acquired == false) {
58582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        acquiredBuffer = mSurfaceBuffers + nextAcquire;
58682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
58782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        querySurfaceRenderStatus(acquiredBuffer);
58882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
58982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (acquiredBuffer->asReferernce == false && acquiredBuffer->renderBuffer.renderDone == true && acquiredBuffer->renderBuffer.driverRenderDone == true) {
59082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // this is potential buffer for acquisition. Check if it is referenced by other surface for frame skipping
59182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VideoSurfaceBuffer *temp;
59282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            acquired = true;
59382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            for (int i = 0; i < mNumSurfaces; i++) {
59482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (i == nextAcquire) {
59582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    continue;
59682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
59782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                temp = mSurfaceBuffers + i;
59882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // use mSurfaces[nextAcquire] instead of acquiredBuffer->renderBuffer.surface as its the actual surface to use.
59982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (temp->renderBuffer.surface == mSurfaces[nextAcquire] &&
60082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    temp->renderBuffer.renderDone == false) {
60182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    ITRACE("Surface is referenced by other surface buffer.");
60282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    acquired = false;
60382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    break;
60482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
60582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
60682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
60782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (acquired) {
60882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
60982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
61082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        nextAcquire++;
61182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (nextAcquire == mNumSurfaces) {
61282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            nextAcquire = 0;
61382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
61482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (nextAcquire == mSurfaceAcquirePos) {
61582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_NO_SURFACE;
61682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
61782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
61882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
61982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (acquired == false) {
62082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_SURFACE;
62182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
62282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
62382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer = acquiredBuffer;
62482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceAcquirePos = nextAcquire;
62582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
62682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // set surface again as surface maybe reset by skipped frame.
62782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // skipped frame is a "non-coded frame" and decoder needs to duplicate the previous reference frame as the output.
62882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.surface = mSurfaces[mSurfaceAcquirePos];
62982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaceUserPtr && mAcquiredBuffer->mappedData) {
63082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->mappedData->data = mSurfaceUserPtr[mSurfaceAcquirePos];
63182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
63282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.timeStamp = INVALID_PTS;
63382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.display = mVADisplay;
63482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.flag = 0;
63582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.renderDone = false;
63682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->asReferernce = false;
63782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.errBuf.errorNumber = 0;
63882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.errBuf.timeStamp = INVALID_PTS;
63982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
64082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
64182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
64282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
64382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::outputSurfaceBuffer(void) {
64482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
64582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer == NULL) {
64682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
64782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
64882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
64982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
65082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mRawOutput) {
65182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = getRawDataFromSurface();
65282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS();
65382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
65482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
65582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // frame is successfly decoded to the current surface,  it is ready for output
65682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mShowFrame) {
65782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->renderBuffer.renderDone = false;
65882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
65982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->renderBuffer.renderDone = true;
66082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
66182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
66282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // decoder must set "asReference and referenceFrame" flags properly
66382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
66482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // update reference frames
66582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer->referenceFrame) {
66682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mManageReference) {
66782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // managing reference for MPEG4/H.263/WMV.
66882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // AVC should manage reference frame in a different way
66982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mForwardReference != NULL) {
67082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // this foward reference is no longer needed
67182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mForwardReference->asReferernce = false;
67282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
67382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // Forware reference for either P or B frame prediction
67482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mForwardReference = mLastReference;
67582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->asReferernce = true;
67682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
67782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
67882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // the last reference frame.
67982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mLastReference = mAcquiredBuffer;
68082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
68182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // add to the output list
68282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mShowFrame) {
68382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mOutputHead == NULL) {
68482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mOutputHead = mAcquiredBuffer;
68582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
68682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mOutputTail->next = mAcquiredBuffer;
68782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
68882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputTail = mAcquiredBuffer;
68982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputTail->next = NULL;
69082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
69182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
69282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //VTRACE("Pushing POC %d to queue (pts = %.2f)", mAcquiredBuffer->pictureOrder, mAcquiredBuffer->renderBuffer.timeStamp/1E6);
69382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
69482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer = NULL;
69582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceAcquirePos = (mSurfaceAcquirePos  + 1 ) % mNumSurfaces;
69682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
69782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
69882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
69982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::releaseSurfaceBuffer(void) {
70082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer == NULL) {
70182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // this is harmless error
70282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
70382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
70482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
70582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // frame is not decoded to the acquired buffer, current surface is invalid, and can't be output.
70682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->asReferernce = false;
70782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.renderDone = true;
70882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer = NULL;
70982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
71082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
71182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
71282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::flushSurfaceBuffers(void) {
71382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    endDecodingFrame(true);
71482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = NULL;
71582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    while (mOutputHead) {
71682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputHead->renderBuffer.renderDone = true;
71782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p = mOutputHead;
71882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mOutputHead = mOutputHead->next;
71982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p->next = NULL;
72082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
72182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mOutputHead = NULL;
72282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mOutputTail = NULL;
72382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
72482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
72582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::endDecodingFrame(bool dropFrame) {
72682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status = DECODE_SUCCESS;
72782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
72882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
72982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mDecodingFrame == false) {
73082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mAcquiredBuffer != NULL) {
73182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            //ETRACE("mAcquiredBuffer is not NULL. Implementation bug.");
73282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            releaseSurfaceBuffer();
73382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            status = DECODE_FAIL;
73482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
73582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return status;
73682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
73782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // return through exit label to reset mDecodingFrame
73882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer == NULL) {
73982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
74082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = DECODE_FAIL;
74182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        goto exit;
74282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
74382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
74482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaEndPicture(mVADisplay, mVAContext);
74582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (vaStatus != VA_STATUS_SUCCESS) {
74682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        releaseSurfaceBuffer();
74782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("vaEndPicture failed. vaStatus = %d", vaStatus);
74882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = DECODE_DRIVER_FAIL;
74982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        goto exit;
75082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
75182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
75282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (dropFrame) {
75382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // we are asked to drop this decoded picture
75482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VTRACE("Frame dropped in endDecodingFrame");
75582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaSyncSurface(mVADisplay, mAcquiredBuffer->renderBuffer.surface);
75682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        releaseSurfaceBuffer();
75782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        goto exit;
75882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
75982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = outputSurfaceBuffer();
76082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // fall through
76182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONexit:
76282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mDecodingFrame = false;
76382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return status;
76482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
76582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
76682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
76782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::setupVA(uint32_t numSurface, VAProfile profile, uint32_t numExtraSurface) {
76882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus = VA_STATUS_SUCCESS;
76982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
77082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAConfigAttrib attrib;
77182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
77282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted) {
77382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
77482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
77582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
77682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mRotationDegrees = 0;
77782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER){
77882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifdef TARGET_HAS_VPP
77982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber - mConfigBuffer.vppBufferNum)
78082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
78182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber)
78282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
78382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_FORMAT_CHANGE;
78482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
78582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        numSurface = mConfigBuffer.surfaceNumber;
78682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // if format has been changed in USE_NATIVE_GRAPHIC_BUFFER mode,
78782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // we can not setupVA here when the graphic buffer resolution is smaller than the resolution decoder really needs
78882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mSizeChanged) {
78982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mVideoFormatInfo.surfaceWidth < mVideoFormatInfo.width || mVideoFormatInfo.surfaceHeight < mVideoFormatInfo.height) {
79082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mSizeChanged = false;
79182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return DECODE_FORMAT_CHANGE;
79282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
79382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
79482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
79582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
79682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // TODO: validate profile
79782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (numSurface == 0) {
79882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
79982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
80082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
80182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConfigBuffer.flag & HAS_MINIMUM_SURFACE_NUMBER) {
80282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (numSurface < mConfigBuffer.surfaceNumber) {
80382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("surface to allocated %d is less than minimum number required %d",
80482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    numSurface, mConfigBuffer.surfaceNumber);
80582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            numSurface = mConfigBuffer.surfaceNumber;
80682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
80782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
80882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
80982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVADisplay != NULL) {
81082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("VA is partially started.");
81182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
81282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
81382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
81482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Display is defined as "unsigned int"
81582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_HYBRID_DRIVER
81682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mDisplay = new Display;
81782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    *mDisplay = ANDROID_DISPLAY_HANDLE;
81882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
81982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (profile >= VAProfileH264Baseline && profile <= VAProfileVC1Advanced) {
82082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("Using GEN driver");
82182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mDisplay = "libva_driver_name=i965";
82282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mUseGEN = true;
82382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
82482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("Using PVR driver");
82582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mDisplay = "libva_driver_name=pvr";
82682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mUseGEN = false;
82782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
82882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
82982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
83082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVADisplay = vaGetDisplay(mDisplay);
83182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVADisplay == NULL) {
83282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("vaGetDisplay failed.");
83382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_DRIVER_FAIL;
83482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
83582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
83682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int majorVersion, minorVersion;
83782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaInitialize(mVADisplay, &majorVersion, &minorVersion);
83882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaInitialize");
83982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
84082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((int32_t)profile != VAProfileSoftwareDecoding) {
84182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
84282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = checkHardwareCapability();
84382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("checkHardwareCapability");
84482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
84582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
84682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = getCodecSpecificConfigs(profile, &mVAConfig);
84782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("getCodecSpecificAttributes");
84882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
84982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        //We are requesting RT attributes
85082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attrib.type = VAConfigAttribRTFormat;
85182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attrib.value = VA_RT_FORMAT_YUV420;
85282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
85382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateConfig(
85482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVADisplay,
85582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                profile,
85682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                VAEntrypointVLD,
85782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &attrib,
85882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                1,
85982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &mVAConfig);
86082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreateConfig");
86182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
86282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
86382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
86482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNumSurfaces = numSurface;
86582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNumExtraSurfaces = numExtraSurface;
86682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaces = new VASurfaceID [mNumSurfaces + mNumExtraSurfaces];
86782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mExtraSurfaces = mSurfaces + mNumSurfaces;
86882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaces == NULL) {
86982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_MEMORY_FAIL;
87082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
87182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
87282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    setRenderRect();
87382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
87482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t format = VA_RT_FORMAT_YUV420;
87582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION) {
87682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_AVC_SHORT_FORMAT
87782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        format |= VA_RT_FORMAT_PROTECTED;
87882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("Surface is protected.");
87982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
88082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
88182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) {
88282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VASurfaceAttrib attribs[2];
88382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib = new VASurfaceAttribExternalBuffers;
88482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mVASurfaceAttrib == NULL) {
88582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_MEMORY_FAIL;
88682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
88782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
88882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->buffers= (unsigned long *)malloc(sizeof(unsigned long)*mNumSurfaces);
88982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mVASurfaceAttrib->buffers == NULL) {
89082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_MEMORY_FAIL;
89182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
89282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->num_buffers = mNumSurfaces;
89382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->pixel_format = VA_FOURCC_NV12;
89482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->width = mVideoFormatInfo.surfaceWidth;
89582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->height = mVideoFormatInfo.surfaceHeight;
89682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->data_size = mConfigBuffer.graphicBufferStride * mVideoFormatInfo.surfaceHeight * 1.5;
89782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->num_planes = 2;
89882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->pitches[0] = mConfigBuffer.graphicBufferStride;
89982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->pitches[1] = mConfigBuffer.graphicBufferStride;
90082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->pitches[2] = 0;
90182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->pitches[3] = 0;
90282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->offsets[0] = 0;
90382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->offsets[1] = mConfigBuffer.graphicBufferStride * mVideoFormatInfo.surfaceHeight;
90482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->offsets[2] = 0;
90582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->offsets[3] = 0;
90682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->private_data = (void *)mConfigBuffer.nativeWindow;
90782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib->flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
90882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mConfigBuffer.flag & USE_TILING_MEMORY)
90982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVASurfaceAttrib->flags |= VA_SURFACE_EXTBUF_DESC_ENABLE_TILING;
91082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
91182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int i = 0; i < mNumSurfaces; i++) {
91282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVASurfaceAttrib->buffers[i] = (unsigned long)mConfigBuffer.graphicBufferHandler[i];
91382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
91482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
91582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
91682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
91782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attribs[0].value.type = VAGenericValueTypeInteger;
91882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
91982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
92082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
92182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
92282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attribs[1].value.type = VAGenericValueTypePointer;
92382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attribs[1].value.value.p = (void *)mVASurfaceAttrib;
92482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
92582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateSurfaces(
92682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
92782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            format,
92882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.surfaceWidth,
92982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.surfaceHeight,
93082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaces,
93182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mNumSurfaces,
93282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            attribs,
93382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            2);
93482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
93582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
93682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateSurfaces(
93782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
93882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            format,
93982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.width,
94082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.height,
94182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaces,
94282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mNumSurfaces,
94382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            NULL,
94482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            0);
94582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceWidth = mVideoFormatInfo.width;
94682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.surfaceHeight = mVideoFormatInfo.height;
94782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
94882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateSurfaces");
94982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
95082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mNumExtraSurfaces != 0) {
95182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateSurfaces(
95282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
95382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            format,
95482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.surfaceWidth,
95582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.surfaceHeight,
95682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExtraSurfaces,
95782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mNumExtraSurfaces,
95882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            NULL,
95982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            0);
96082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreateSurfaces");
96182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
96282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
96382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.surfaceNumber = mNumSurfaces;
96482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.ctxSurfaces = mSurfaces;
96582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
96682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((int32_t)profile != VAProfileSoftwareDecoding) {
96782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateContext(
96882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVADisplay,
96982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVAConfig,
97082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVideoFormatInfo.surfaceWidth,
97182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVideoFormatInfo.surfaceHeight,
97282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                0,
97382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mSurfaces,
97482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNumSurfaces + mNumExtraSurfaces,
97582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &mVAContext);
97682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreateContext");
97782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
97882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
97982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceBuffers = new VideoSurfaceBuffer [mNumSurfaces];
98082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaceBuffers == NULL) {
98182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_MEMORY_FAIL;
98282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
98382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    initSurfaceBuffer(true);
98482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
98582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((int32_t)profile == VAProfileSoftwareDecoding) {
98682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // derive user pointer from surface for direct access
98782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = mapSurface();
98882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("mapSurface")
98982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
99082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
99182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    setRotationDegrees(mConfigBuffer.rotationDegrees);
99282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
99382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVAStarted = true;
99482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
99582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
99682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
99782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::terminateVA(void) {
99882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSignalBufferSize = 0;
99982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
100082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         mSignalBufferPre[i] = NULL;
100182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
100282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
100382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAStarted == false) {
100482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // VA hasn't been started yet
100582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
100682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
100782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
100882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaceBuffers) {
100982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int32_t i = 0; i < mNumSurfaces; i++) {
101082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mSurfaceBuffers[i].renderBuffer.rawData) {
101182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (mSurfaceBuffers[i].renderBuffer.rawData->data) {
101282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    delete [] mSurfaceBuffers[i].renderBuffer.rawData->data;
101382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
101482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                delete mSurfaceBuffers[i].renderBuffer.rawData;
101582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
101682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mSurfaceBuffers[i].mappedData) {
101782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // don't  delete data pointer as it is mapped from surface
101882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                delete mSurfaceBuffers[i].mappedData;
101982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
102082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
102182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete [] mSurfaceBuffers;
102282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers = NULL;
102382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
102482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
102582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVASurfaceAttrib) {
102682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mVASurfaceAttrib->buffers) free(mVASurfaceAttrib->buffers);
102782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete mVASurfaceAttrib;
102882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVASurfaceAttrib = NULL;
102982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
103082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
103182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
103282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaceUserPtr) {
103382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete [] mSurfaceUserPtr;
103482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceUserPtr = NULL;
103582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
103682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
103782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaces)
103882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    {
103982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaDestroySurfaces(mVADisplay, mSurfaces, mNumSurfaces + mNumExtraSurfaces);
104082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete [] mSurfaces;
104182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaces = NULL;
104282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
104382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
104482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAContext != VA_INVALID_ID) {
104582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         vaDestroyContext(mVADisplay, mVAContext);
104682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         mVAContext = VA_INVALID_ID;
104782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
104882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
104982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVAConfig != VA_INVALID_ID) {
105082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaDestroyConfig(mVADisplay, mVAConfig);
105182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAConfig = VA_INVALID_ID;
105282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
105382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
105482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVADisplay) {
105582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaTerminate(mVADisplay);
105682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay = NULL;
105782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
105882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
105982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mDisplay) {
106082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_HYBRID_DRIVER
106182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete mDisplay;
106282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
106382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mDisplay = NULL;
106482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
106582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
106682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVAStarted = false;
106782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mInitialized = false;
106882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mErrReportEnabled = false;
106982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
107082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
107182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
107282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::parseBuffer(uint8_t *buffer, int32_t size, bool config, void** vbpData) {
107382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON     // DON'T check if mVAStarted == true
107482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle == NULL) {
107582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
107682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
107782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
107882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t vbpStatus;
107982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer == NULL || size <= 0) {
108082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
108182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
108282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
108382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint8_t configFlag = config ? 1 : 0;
108482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbpStatus = mParserParse(mParserHandle, buffer, size, configFlag);
108582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VBP_STATUS("vbp_parse");
108682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
108782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbpStatus = mParserQuery(mParserHandle, vbpData);
108882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VBP_STATUS("vbp_query");
108982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
109082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
109182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
109282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
109382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
109482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
109582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::mapSurface(void) {
109682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus = VA_STATUS_SUCCESS;
109782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAImage image;
109882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint8_t *userPtr;
109982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSurfaceUserPtr = new uint8_t* [mNumSurfaces];
110082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSurfaceUserPtr == NULL) {
110182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_MEMORY_FAIL;
110282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
110382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
110482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i< mNumSurfaces; i++) {
110582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaDeriveImage(mVADisplay, mSurfaces[i], &image);
110682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaDeriveImage");
110782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaMapBuffer(mVADisplay, image.buf, (void**)&userPtr);
110882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaMapBuffer");
110982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceUserPtr[i] = userPtr;
111082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData = new VideoFrameRawData;
111182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mSurfaceBuffers[i].mappedData == NULL) {
111282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_MEMORY_FAIL;
111382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
111482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->own = false; // derived from surface so can't be released
111582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->data = NULL;  // specified during acquireSurfaceBuffer
111682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->fourcc = image.format.fourcc;
111782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->width = mVideoFormatInfo.width;
111882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->height = mVideoFormatInfo.height;
111982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].mappedData->size = image.data_size;
112082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int pi = 0; pi < 3; pi++) {
112182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].mappedData->pitch[pi] = image.pitches[pi];
112282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].mappedData->offset[pi] = image.offsets[pi];
112382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
112482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // debug information
112582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (image.pitches[0] != image.pitches[1] ||
112682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            image.width != mVideoFormatInfo.width ||
112782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            image.height != mVideoFormatInfo.height ||
112882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            image.offsets[0] != 0) {
112982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("Unexpected VAImage format, w = %d, h = %d, offset = %d", image.width, image.height, image.offsets[0]);
113082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
113182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // TODO: do we need to unmap buffer?
113282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        //vaStatus = vaUnmapBuffer(mVADisplay, image.buf);
113382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        //CHECK_VA_STATUS("vaMapBuffer");
113482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaDestroyImage(mVADisplay,image.image_id);
113582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaDestroyImage");
113682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
113782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
113882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
113982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
114082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
114182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::getRawDataFromSurface(VideoRenderBuffer *renderBuffer, uint8_t *pRawData, uint32_t *pSize, bool internal) {
114282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (internal) {
114382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mAcquiredBuffer == NULL) {
114482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_FAIL;
114582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
114682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        renderBuffer = &(mAcquiredBuffer->renderBuffer);
114782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
114882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
114982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
115082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAImageFormat imageFormat;
115182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAImage vaImage;
115282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaSyncSurface(renderBuffer->display, renderBuffer->surface);
115382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaSyncSurface");
115482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
115582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaDeriveImage(renderBuffer->display, renderBuffer->surface, &vaImage);
115682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaDeriveImage");
115782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
115882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    void *pBuf = NULL;
115982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaMapBuffer(renderBuffer->display, vaImage.buf, &pBuf);
116082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaMapBuffer");
116182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
116282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
116382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // size in NV12 format
116482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t cropWidth = mVideoFormatInfo.width - (mVideoFormatInfo.cropLeft + mVideoFormatInfo.cropRight);
116582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t cropHeight = mVideoFormatInfo.height - (mVideoFormatInfo.cropBottom + mVideoFormatInfo.cropTop);
116682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t size = cropWidth  * cropHeight * 3 / 2;
116782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
116882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (internal) {
116982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VideoFrameRawData *rawData = NULL;
117082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (renderBuffer->rawData == NULL) {
117182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            rawData = new VideoFrameRawData;
117282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (rawData == NULL) {
117382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return DECODE_MEMORY_FAIL;
117482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
117582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memset(rawData, 0, sizeof(VideoFrameRawData));
117682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            renderBuffer->rawData = rawData;
117782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
117882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            rawData = renderBuffer->rawData;
117982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
118082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
118182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (rawData->data != NULL && rawData->size != size) {
118282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            delete [] rawData->data;
118382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            rawData->data = NULL;
118482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            rawData->size = 0;
118582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
118682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (rawData->data == NULL) {
118782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            rawData->data = new uint8_t [size];
118882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (rawData->data == NULL) {
118982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return DECODE_MEMORY_FAIL;
119082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
119182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
119282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
119382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->own = true; // allocated by this library
119482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->width = cropWidth;
119582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->height = cropHeight;
119682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->pitch[0] = cropWidth;
119782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->pitch[1] = cropWidth;
119882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->pitch[2] = 0;  // interleaved U/V, two planes
119982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->offset[0] = 0;
120082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->offset[1] = cropWidth * cropHeight;
120182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->offset[2] = cropWidth * cropHeight * 3 / 2;
120282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->size = size;
120382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rawData->fourcc = 'NV12';
120482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
120582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        pRawData = rawData->data;
120682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
120782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        *pSize = size;
120882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
120982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
121082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (size == (int32_t)vaImage.data_size) {
121182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifdef  __SSE4_1__
121282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        stream_memcpy(pRawData, pBuf, size);
121382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
121482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        memcpy(pRawData, pBuf, size);
121582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
121682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
121782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // copy Y data
121882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint8_t *src = (uint8_t*)pBuf;
121982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint8_t *dst = pRawData;
122082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint32_t row = 0;
122182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (row = 0; row < cropHeight; row++) {
122282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifdef  __SSE4_1__
122382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            stream_memcpy(dst, src, cropWidth);
122482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
122582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(dst, src, cropWidth);
122682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
122782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dst += cropWidth;
122882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            src += vaImage.pitches[0];
122982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
123082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // copy interleaved V and  U data
123182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        src = (uint8_t*)pBuf + vaImage.offsets[1];
123282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (row = 0; row < cropHeight / 2; row++) {
123382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifdef  __SSE4_1__
123482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            stream_memcpy(dst, src, cropWidth);
123582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
123682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(dst, src, cropWidth);
123782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
123882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dst += cropWidth;
123982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            src += vaImage.pitches[1];
124082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
124182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
124282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
124382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaUnmapBuffer(renderBuffer->display, vaImage.buf);
124482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaUnmapBuffer");
124582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
124682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaDestroyImage(renderBuffer->display, vaImage.image_id);
124782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaDestroyImage");
124882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
124982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
125082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
125182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
125282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::initSurfaceBuffer(bool reset) {
125382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
125482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (useGraphicBuffer && reset) {
125582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        pthread_mutex_lock(&mLock);
125682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
125782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < mNumSurfaces; i++) {
125882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.display = mVADisplay;
125982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.surface = VA_INVALID_SURFACE;  // set in acquireSurfaceBuffer
126082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.flag = 0;
126182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.scanFormat = VA_FRAME_PICTURE;
126282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.timeStamp = 0;
126382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].referenceFrame = false;
126482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].asReferernce= false;
126582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].pictureOrder = 0;
126682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].next = NULL;
126782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (reset == true) {
126882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].renderBuffer.rawData = NULL;
126982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].mappedData = NULL;
127082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
127182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (useGraphicBuffer) {
127282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (reset) {
127382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               mSurfaceBuffers[i].renderBuffer.graphicBufferHandle = mConfigBuffer.graphicBufferHandler[i];
127482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               mSurfaceBuffers[i].renderBuffer.renderDone = false; //default false
127582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               for (uint32_t j = 0; j < mSignalBufferSize; j++) {
127682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                   if(mSignalBufferPre[j] != NULL && mSignalBufferPre[j] == mSurfaceBuffers[i].renderBuffer.graphicBufferHandle) {
127782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                      mSurfaceBuffers[i].renderBuffer.renderDone = true;
127882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                      VTRACE("initSurfaceBuffer set renderDone = true index = %d", i);
127982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                      mSignalBufferPre[j] = NULL;
128082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                      break;
128182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                   }
128282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               }
128382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
128482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               mSurfaceBuffers[i].renderBuffer.renderDone = false;
128582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
128682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
128782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].renderBuffer.graphicBufferHandle = NULL;
128882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSurfaceBuffers[i].renderBuffer.renderDone = true;
128982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
129082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSurfaceBuffers[i].renderBuffer.graphicBufferIndex = i;
129182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
129282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
129382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (useGraphicBuffer && reset) {
129482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mInitialized = true;
129582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSignalBufferSize = 0;
129682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        pthread_mutex_unlock(&mLock);
129782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
129882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
129982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
130082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::signalRenderDone(void * graphichandler) {
130182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (graphichandler == NULL) {
130282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
130382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
130482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_lock(&mLock);
130582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int i = 0;
130682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mInitialized) {
130782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mSignalBufferSize >= MAX_GRAPHIC_BUFFER_NUM) {
130882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            pthread_mutex_unlock(&mLock);
130982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_INVALID_DATA;
131082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
131182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSignalBufferPre[mSignalBufferSize++] = graphichandler;
131282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VTRACE("SignalRenderDoneFlag mInitialized = false graphichandler = %p, mSignalBufferSize = %d", graphichandler, mSignalBufferSize);
131382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
131482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (!(mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) {
131582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            pthread_mutex_unlock(&mLock);
131682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_SUCCESS;
131782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
131882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (i = 0; i < mNumSurfaces; i++) {
131982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mSurfaceBuffers[i].renderBuffer.graphicBufferHandle == graphichandler) {
132082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mSurfaceBuffers[i].renderBuffer.renderDone = true;
132182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                VTRACE("SignalRenderDoneFlag mInitialized = true index = %d", i);
132282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON               break;
132382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON           }
132482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
132582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
132682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pthread_mutex_unlock(&mLock);
132782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
132882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
132982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
133082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
133182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
133282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::querySurfaceRenderStatus(VideoSurfaceBuffer* surface) {
133382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VASurfaceStatus surfStat = VASurfaceReady;
133482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus    vaStat = VA_STATUS_SUCCESS;
133582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
133682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!surface) {
133782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOGW("SurfaceBuffer not ready yet");
133882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return;
133982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
134082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    surface->renderBuffer.driverRenderDone = true;
134182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
134282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_GEN_HW
134382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (surface->renderBuffer.surface != VA_INVALID_SURFACE &&
134482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON       (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) {
134582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
134682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStat = vaQuerySurfaceStatus(mVADisplay, surface->renderBuffer.surface, &surfStat);
134782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
134882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if ((vaStat == VA_STATUS_SUCCESS) && (surfStat != VASurfaceReady))
134982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            surface->renderBuffer.driverRenderDone = false;
135082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
135182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
135282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
135382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
135482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
135582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
135682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON// This function should be called before start() to load different type of parsers
135782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
135882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::setParserType(_vbp_parser_type type) {
135982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((int32_t)type != VBP_INVALID) {
136082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("Parser Type = %d", (int32_t)type);
136182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mParserType = type;
136282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
136382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
136482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Invalid parser type = %d", (int32_t)type);
136582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
136682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
136782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
136882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
136982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::updateBuffer(uint8_t *buffer, int32_t size, void** vbpData) {
137082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle == NULL) {
137182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
137282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
137382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
137482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t vbpStatus;
137582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer == NULL || size <= 0) {
137682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
137782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
137882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
137982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbpStatus = mParserUpdate(mParserHandle, buffer, size, vbpData);
138082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VBP_STATUS("vbp_update");
138182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
138282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
138382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
138482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
138582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::queryBuffer(void** vbpData) {
138682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mParserHandle == NULL) {
138782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_PARSER;
138882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
138982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
139082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t vbpStatus;
139182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbpStatus = mParserQuery(mParserHandle, vbpData);
139282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VBP_STATUS("vbp_query");
139382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
139482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
139582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
139682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
139782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::getCodecSpecificConfigs(VAProfile profile, VAConfigID *config) {
139882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
139982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAConfigAttrib attrib;
140082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib.type = VAConfigAttribRTFormat;
140182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib.value = VA_RT_FORMAT_YUV420;
140282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
140382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (config == NULL) {
140482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Invalid parameter!");
140582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
140682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
140782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
140882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateConfig(
140982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
141082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            profile,
141182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAEntrypointVLD,
141282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &attrib,
141382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            1,
141482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            config);
141582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
141682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateConfig");
141782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
141882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
141982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
142082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
142182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderBase::checkHardwareCapability() {
142282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
142382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
142482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
142582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::drainDecodingErrors(VideoErrorBuffer *outErrBuf, VideoRenderBuffer *currentSurface) {
142682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mErrReportEnabled && outErrBuf && currentSurface) {
142782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        memcpy(outErrBuf, &(currentSurface->errBuf), sizeof(VideoErrorBuffer));
142882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
142982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        currentSurface->errBuf.errorNumber = 0;
143082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        currentSurface->errBuf.timeStamp = INVALID_PTS;
143182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
143282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (outErrBuf)
143382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VTRACE("%s: error number is %d", __FUNCTION__, outErrBuf->errorNumber);
143482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
143582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
143682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::fillDecodingErrors(VideoRenderBuffer *currentSurface) {
143782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus ret;
143882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
143982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mErrReportEnabled) {
144082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        currentSurface->errBuf.timeStamp = currentSurface->timeStamp;
144182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // TODO: is 10 a suitable number?
144282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VASurfaceDecodeMBErrors *err_drv_output = NULL;
144382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ret = vaQuerySurfaceError(mVADisplay, currentSurface->surface, VA_STATUS_ERROR_DECODING_ERROR, (void **)&err_drv_output);
144482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (ret || !err_drv_output) {
144582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("vaQuerySurfaceError failed.");
144682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return;
144782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
144882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
144982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int offset =  0x1 & currentSurface->errBuf.errorNumber;// offset is either 0 or 1
145082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int i = 0; i < MAX_ERR_NUM - offset; i++) {
145182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (err_drv_output[i].status != -1) {
145282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                currentSurface->errBuf.errorNumber++;
145382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                currentSurface->errBuf.errorArray[i + offset].type = DecodeMBError;
145482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.start_mb = err_drv_output[i].start_mb;
145582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.end_mb = err_drv_output[i].end_mb;
145682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                currentSurface->errBuf.errorArray[i + offset].num_mbs = err_drv_output[i].end_mb - err_drv_output[i].start_mb + 1;
145782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                ITRACE("Error Index[%d]: type = %d, start_mb = %d, end_mb = %d",
145882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    currentSurface->errBuf.errorNumber - 1,
145982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    currentSurface->errBuf.errorArray[i + offset].type,
146082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.start_mb,
146182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.end_mb);
146282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else break;
146382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
146482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("%s: error number of current surface is %d, timestamp @%llu",
146582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            __FUNCTION__, currentSurface->errBuf.errorNumber, currentSurface->timeStamp);
146682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
146782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
146882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
146982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::setRotationDegrees(int32_t rotationDegrees) {
147082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mRotationDegrees == rotationDegrees) {
147182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return;
147282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
147382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
147482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ITRACE("set new rotation degree: %d", rotationDegrees);
147582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VADisplayAttribute rotate;
147682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rotate.type = VADisplayAttribRotation;
147782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rotate.value = VA_ROTATION_NONE;
147882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (rotationDegrees == 0)
147982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rotate.value = VA_ROTATION_NONE;
148082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    else if (rotationDegrees == 90)
148182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rotate.value = VA_ROTATION_90;
148282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    else if (rotationDegrees == 180)
148382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rotate.value = VA_ROTATION_180;
148482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    else if (rotationDegrees == 270)
148582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        rotate.value = VA_ROTATION_270;
148682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
148782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus ret = vaSetDisplayAttributes(mVADisplay, &rotate, 1);
148882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (ret) {
148982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Failed to set rotation degree.");
149082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
149182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mRotationDegrees = rotationDegrees;
149282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
149382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
149482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderBase::setRenderRect() {
149582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
149682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mVADisplay)
149782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return;
149882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
149982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus ret;
150082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VARectangle rect;
150182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rect.x = mVideoFormatInfo.cropLeft;
150282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rect.y = mVideoFormatInfo.cropTop;
150382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rect.width = mVideoFormatInfo.width - (mVideoFormatInfo.cropLeft + mVideoFormatInfo.cropRight);
150482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    rect.height = mVideoFormatInfo.height - (mVideoFormatInfo.cropBottom + mVideoFormatInfo.cropTop);
150582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
150682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VADisplayAttribute render_rect;
150782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    render_rect.type = VADisplayAttribRenderRect;
150882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    render_rect.value = (long)&rect;
150982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
151082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ret = vaSetDisplayAttributes(mVADisplay, &render_rect, 1);
151182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (ret) {
151282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Failed to set rotation degree.");
151382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
151482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
1515