Home | History | Annotate | Download | only in videodecoder
      1 /*
      2 * Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 #include "VideoDecoderBase.h"
     18 #include "VideoDecoderTrace.h"
     19 #include <string.h>
     20 #include <va/va_android.h>
     21 #include <va/va_tpi.h>
     22 #ifdef  __SSE4_1__
     23 #include "use_util_sse4.h"
     24 #endif
     25 
     26 #define INVALID_PTS ((uint64_t)-1)
     27 #define MAXIMUM_POC  0x7FFFFFFF
     28 #define MINIMUM_POC  0x80000000
     29 #define ANDROID_DISPLAY_HANDLE 0x18C34078
     30 
     31 VideoDecoderBase::VideoDecoderBase(const char *mimeType, _vbp_parser_type type)
     32     : mInitialized(false),
     33       mLowDelay(false),
     34       mDisplay(NULL),
     35       mVADisplay(NULL),
     36       mVAContext(VA_INVALID_ID),
     37       mVAConfig(VA_INVALID_ID),
     38       mVAStarted(false),
     39       mCurrentPTS(INVALID_PTS),
     40       mAcquiredBuffer(NULL),
     41       mLastReference(NULL),
     42       mForwardReference(NULL),
     43       mDecodingFrame(false),
     44       mSizeChanged(false),
     45       mShowFrame(true),
     46       mOutputWindowSize(OUTPUT_WINDOW_SIZE),
     47       mRotationDegrees(0),
     48       mErrReportEnabled(false),
     49       mWiDiOn(false),
     50       mRawOutput(false),
     51       mManageReference(true),
     52       mOutputMethod(OUTPUT_BY_PCT),
     53       mNumSurfaces(0),
     54       mSurfaceBuffers(NULL),
     55       mOutputHead(NULL),
     56       mOutputTail(NULL),
     57       mSurfaces(NULL),
     58       mVASurfaceAttrib(NULL),
     59       mSurfaceUserPtr(NULL),
     60       mSurfaceAcquirePos(0),
     61       mNextOutputPOC(MINIMUM_POC),
     62       mParserType(type),
     63       mParserHandle(NULL),
     64       mSignalBufferSize(0) {
     65 
     66     memset(&mVideoFormatInfo, 0, sizeof(VideoFormatInfo));
     67     memset(&mConfigBuffer, 0, sizeof(mConfigBuffer));
     68     for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
     69          mSignalBufferPre[i] = NULL;
     70     }
     71     pthread_mutex_init(&mLock, NULL);
     72     mVideoFormatInfo.mimeType = strdup(mimeType);
     73     mUseGEN = false;
     74     mLibHandle = NULL;
     75     mParserOpen = NULL;
     76     mParserClose = NULL;
     77     mParserParse = NULL;
     78     mParserQuery = NULL;
     79     mParserFlush = NULL;
     80     mParserUpdate = NULL;
     81 }
     82 
     83 VideoDecoderBase::~VideoDecoderBase() {
     84     pthread_mutex_destroy(&mLock);
     85     stop();
     86     free(mVideoFormatInfo.mimeType);
     87 }
     88 
     89 Decode_Status VideoDecoderBase::start(VideoConfigBuffer *buffer) {
     90     if (buffer == NULL) {
     91         return DECODE_INVALID_DATA;
     92     }
     93 
     94     if (mParserHandle != NULL) {
     95         WTRACE("Decoder has already started.");
     96         return DECODE_SUCCESS;
     97     }
     98     mLibHandle = dlopen("libmixvbp.so", RTLD_NOW);
     99     if (mLibHandle == NULL) {
    100        return DECODE_NO_PARSER;
    101     }
    102     mParserOpen = (OpenFunc)dlsym(mLibHandle, "vbp_open");
    103     mParserClose = (CloseFunc)dlsym(mLibHandle, "vbp_close");
    104     mParserParse = (ParseFunc)dlsym(mLibHandle, "vbp_parse");
    105     mParserQuery = (QueryFunc)dlsym(mLibHandle, "vbp_query");
    106     mParserFlush = (FlushFunc)dlsym(mLibHandle, "vbp_flush");
    107     if (mParserOpen == NULL || mParserClose == NULL || mParserParse == NULL
    108         || mParserQuery == NULL || mParserFlush == NULL) {
    109         return DECODE_NO_PARSER;
    110     }
    111 #if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
    112     mParserUpdate = (UpdateFunc)dlsym(mLibHandle, "vbp_update");
    113     if (mParserUpdate == NULL) {
    114         return DECODE_NO_PARSER;
    115     }
    116 #endif
    117     if ((int32_t)mParserType != VBP_INVALID) {
    118         ITRACE("mParserType = %d", mParserType);
    119         if (mParserOpen(mParserType, &mParserHandle) != VBP_OK) {
    120             ETRACE("Failed to open VBP parser.");
    121             return DECODE_NO_PARSER;
    122         }
    123     }
    124     // keep a copy of configure buffer, meta data only. It can be used to override VA setup parameter.
    125     mConfigBuffer = *buffer;
    126     mConfigBuffer.data = NULL;
    127     mConfigBuffer.size = 0;
    128 
    129     mVideoFormatInfo.width = buffer->width;
    130     mVideoFormatInfo.height = buffer->height;
    131     if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) {
    132         mVideoFormatInfo.surfaceWidth = buffer->graphicBufferWidth;
    133         mVideoFormatInfo.surfaceHeight = buffer->graphicBufferHeight;
    134     }
    135     mLowDelay = buffer->flag & WANT_LOW_DELAY;
    136     mRawOutput = buffer->flag & WANT_RAW_OUTPUT;
    137     if (mRawOutput) {
    138         WTRACE("Output is raw data.");
    139     }
    140 
    141     return DECODE_SUCCESS;
    142 }
    143 
    144 
    145 Decode_Status VideoDecoderBase::reset(VideoConfigBuffer *buffer) {
    146     if (buffer == NULL) {
    147         return DECODE_INVALID_DATA;
    148     }
    149 
    150     // if VA is already started, terminate VA as graphic buffers are reallocated by omxcodec
    151     terminateVA();
    152 
    153     // reset the mconfigBuffer to pass it for startVA.
    154     mConfigBuffer = *buffer;
    155     mConfigBuffer.data = NULL;
    156     mConfigBuffer.size = 0;
    157 
    158     mVideoFormatInfo.width = buffer->width;
    159     mVideoFormatInfo.height = buffer->height;
    160     if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) {
    161         mVideoFormatInfo.surfaceWidth = buffer->graphicBufferWidth;
    162         mVideoFormatInfo.surfaceHeight = buffer->graphicBufferHeight;
    163     }
    164     mVideoFormatInfo.actualBufferNeeded = mConfigBuffer.surfaceNumber;
    165     mLowDelay = buffer->flag & WANT_LOW_DELAY;
    166     mRawOutput = buffer->flag & WANT_RAW_OUTPUT;
    167     if (mRawOutput) {
    168         WTRACE("Output is raw data.");
    169     }
    170     return DECODE_SUCCESS;
    171 }
    172 
    173 
    174 
    175 void VideoDecoderBase::stop(void) {
    176     terminateVA();
    177 
    178     mCurrentPTS = INVALID_PTS;
    179     mAcquiredBuffer = NULL;
    180     mLastReference = NULL;
    181     mForwardReference = NULL;
    182     mDecodingFrame = false;
    183     mSizeChanged = false;
    184 
    185     // private variables
    186     mLowDelay = false;
    187     mRawOutput = false;
    188     mNumSurfaces = 0;
    189     mSurfaceAcquirePos = 0;
    190     mNextOutputPOC = MINIMUM_POC;
    191     mVideoFormatInfo.valid = false;
    192     if (mParserHandle){
    193         mParserClose(mParserHandle);
    194         mParserHandle = NULL;
    195     }
    196     if (mLibHandle) {
    197         dlclose(mLibHandle);
    198         mLibHandle = NULL;
    199     }
    200 }
    201 
    202 void VideoDecoderBase::flush(void) {
    203     if (mVAStarted == false) {
    204         // nothing to flush at this stage
    205         return;
    206     }
    207 
    208     endDecodingFrame(true);
    209 
    210     VideoSurfaceBuffer *p = mOutputHead;
    211     // check if there's buffer with DRC flag in the output queue
    212     while (p) {
    213         if (p->renderBuffer.flag & IS_RESOLUTION_CHANGE) {
    214             mSizeChanged = true;
    215             break;
    216         }
    217         p = p->next;
    218     }
    219     // avoid setting mSurfaceAcquirePos  to 0 as it may cause tearing
    220     // (surface is still being rendered)
    221     mSurfaceAcquirePos = (mSurfaceAcquirePos  + 1) % mNumSurfaces;
    222     mNextOutputPOC = MINIMUM_POC;
    223     mCurrentPTS = INVALID_PTS;
    224     mAcquiredBuffer = NULL;
    225     mLastReference = NULL;
    226     mForwardReference = NULL;
    227     mOutputHead = NULL;
    228     mOutputTail = NULL;
    229     mDecodingFrame = false;
    230 
    231     // flush vbp parser
    232     if (mParserHandle && (mParserFlush(mParserHandle) != VBP_OK)) {
    233         WTRACE("Failed to flush parser. Continue");
    234     }
    235 
    236     // initialize surface buffer without resetting mapped/raw data
    237     initSurfaceBuffer(false);
    238 
    239 }
    240 
    241 void VideoDecoderBase::freeSurfaceBuffers(void) {
    242     if (mVAStarted == false) {
    243         // nothing to free surface buffers at this stage
    244         return;
    245     }
    246 
    247     pthread_mutex_lock(&mLock);
    248 
    249     endDecodingFrame(true);
    250 
    251     // if VA is already started, terminate VA as graphic buffers are reallocated by omxcodec
    252     terminateVA();
    253 
    254     pthread_mutex_unlock(&mLock);
    255 }
    256 
    257 const VideoFormatInfo* VideoDecoderBase::getFormatInfo(void) {
    258     return &mVideoFormatInfo;
    259 }
    260 
    261 const VideoRenderBuffer* VideoDecoderBase::getOutput(bool draining, VideoErrorBuffer *outErrBuf) {
    262     VAStatus vaStatus;
    263     if (mVAStarted == false) {
    264         return NULL;
    265     }
    266     bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
    267 
    268     if (draining) {
    269         // complete decoding the last frame and ignore return
    270         endDecodingFrame(false);
    271     }
    272 
    273     if (mOutputHead == NULL) {
    274         return NULL;
    275     }
    276 
    277     // output by position (the first buffer)
    278     VideoSurfaceBuffer *outputByPos = mOutputHead;
    279 
    280     if (mLowDelay) {
    281         mOutputHead = mOutputHead->next;
    282         if (mOutputHead == NULL) {
    283             mOutputTail = NULL;
    284         }
    285         vaStatus = vaSetTimestampForSurface(mVADisplay, outputByPos->renderBuffer.surface, outputByPos->renderBuffer.timeStamp);
    286         if (useGraphicBuffer && !mUseGEN) {
    287             vaSyncSurface(mVADisplay, outputByPos->renderBuffer.surface);
    288             fillDecodingErrors(&(outputByPos->renderBuffer));
    289         }
    290         if (draining && mOutputTail == NULL) {
    291             outputByPos->renderBuffer.flag |= IS_EOS;
    292         }
    293         drainDecodingErrors(outErrBuf, &(outputByPos->renderBuffer));
    294 
    295         return &(outputByPos->renderBuffer);
    296     }
    297 
    298     VideoSurfaceBuffer *output = NULL;
    299     if (mOutputMethod == OUTPUT_BY_POC) {
    300         output = findOutputByPoc(draining);
    301     } else if (mOutputMethod == OUTPUT_BY_PCT) {
    302         output = findOutputByPct(draining);
    303     } else {
    304         ETRACE("Invalid output method.");
    305         return NULL;
    306     }
    307 
    308     if (output == NULL) {
    309         return NULL;
    310     }
    311 
    312     if (output != outputByPos) {
    313         // remove this output from middle or end of the list
    314         VideoSurfaceBuffer *p = outputByPos;
    315         while (p->next != output) {
    316             p = p->next;
    317         }
    318         p->next = output->next;
    319         if (mOutputTail == output) {
    320             mOutputTail = p;
    321         }
    322     } else {
    323         // remove this output from head of the list
    324         mOutputHead = mOutputHead->next;
    325         if (mOutputHead == NULL) {
    326             mOutputTail = NULL;
    327         }
    328     }
    329     //VTRACE("Output POC %d for display (pts = %.2f)", output->pictureOrder, output->renderBuffer.timeStamp/1E6);
    330     vaStatus = vaSetTimestampForSurface(mVADisplay, output->renderBuffer.surface, output->renderBuffer.timeStamp);
    331 
    332     if (useGraphicBuffer && !mUseGEN) {
    333         vaSyncSurface(mVADisplay, output->renderBuffer.surface);
    334         fillDecodingErrors(&(output->renderBuffer));
    335     }
    336 
    337     if (draining && mOutputTail == NULL) {
    338         output->renderBuffer.flag |= IS_EOS;
    339     }
    340 
    341     drainDecodingErrors(outErrBuf, &(output->renderBuffer));
    342 
    343     return &(output->renderBuffer);
    344 }
    345 
    346 VideoSurfaceBuffer* VideoDecoderBase::findOutputByPts() {
    347     // output by presentation time stamp - buffer with the smallest time stamp is output
    348     VideoSurfaceBuffer *p = mOutputHead;
    349     VideoSurfaceBuffer *outputByPts = NULL;
    350     uint64_t pts = INVALID_PTS;
    351     do {
    352         if ((uint64_t)(p->renderBuffer.timeStamp) <= pts) {
    353             // find buffer with the smallest PTS
    354             pts = p->renderBuffer.timeStamp;
    355             outputByPts = p;
    356         }
    357         p = p->next;
    358     } while (p != NULL);
    359 
    360     return outputByPts;
    361 }
    362 
    363 VideoSurfaceBuffer* VideoDecoderBase::findOutputByPct(bool draining) {
    364     // output by picture coding type (PCT)
    365     // if there is more than one reference frame, the first reference frame is ouput, otherwise,
    366     // output non-reference frame if there is any.
    367 
    368     VideoSurfaceBuffer *p = mOutputHead;
    369     VideoSurfaceBuffer *outputByPct = NULL;
    370     int32_t reference = 0;
    371     do {
    372         if (p->referenceFrame) {
    373             reference++;
    374             if (reference > 1) {
    375                 // mOutputHead must be a reference frame
    376                 outputByPct = mOutputHead;
    377                 break;
    378             }
    379         } else {
    380             // first non-reference frame
    381             outputByPct = p;
    382             break;
    383         }
    384         p = p->next;
    385     } while (p != NULL);
    386 
    387     if (outputByPct == NULL && draining) {
    388         outputByPct = mOutputHead;
    389     }
    390     return  outputByPct;
    391 }
    392 
    393 #if 0
    394 VideoSurfaceBuffer* VideoDecoderBase::findOutputByPoc(bool draining) {
    395     // output by picture order count (POC)
    396     // Output criteria:
    397     // if there is IDR frame (POC == 0), all the frames before IDR must be output;
    398     // Otherwise, if draining flag is set or list is full, frame with the least POC is output;
    399     // Otherwise, NOTHING is output
    400 
    401     int32_t dpbFullness = 0;
    402     for (int32_t i = 0; i < mNumSurfaces; i++) {
    403         // count num of reference frames
    404         if (mSurfaceBuffers[i].asReferernce) {
    405             dpbFullness++;
    406         }
    407     }
    408 
    409     if (mAcquiredBuffer && mAcquiredBuffer->asReferernce) {
    410         // frame is being decoded and is not ready for output yet
    411         dpbFullness--;
    412     }
    413 
    414     VideoSurfaceBuffer *p = mOutputHead;
    415     while (p != NULL) {
    416         // count dpbFullness with non-reference frame in the output queue
    417         if (p->asReferernce == false) {
    418             dpbFullness++;
    419         }
    420         p = p->next;
    421     }
    422 
    423 Retry:
    424     p = mOutputHead;
    425     VideoSurfaceBuffer *outputByPoc = NULL;
    426     int32_t count = 0;
    427     int32_t poc = MAXIMUM_POC;
    428 
    429     do {
    430         if (p->pictureOrder == 0) {
    431             // output picture with the least POC before IDR
    432             if (outputByPoc != NULL) {
    433                 mNextOutputPOC = outputByPoc->pictureOrder + 1;
    434                 return outputByPoc;
    435             } else {
    436                 mNextOutputPOC = MINIMUM_POC;
    437             }
    438         }
    439 
    440         // POC of  the output candidate must not be less than mNextOutputPOC
    441         if (p->pictureOrder < mNextOutputPOC) {
    442             break;
    443         }
    444 
    445         if (p->pictureOrder < poc) {
    446             // update the least POC.
    447             poc = p->pictureOrder;
    448             outputByPoc = p;
    449         }
    450         count++;
    451         p = p->next;
    452     } while (p != NULL && count < mOutputWindowSize);
    453 
    454     if (draining == false && dpbFullness < mOutputWindowSize) {
    455         // list is not  full and we are not  in draining state
    456         // if DPB is already full, one frame must be output
    457         return NULL;
    458     }
    459 
    460     if (outputByPoc == NULL) {
    461         mNextOutputPOC = MINIMUM_POC;
    462         goto Retry;
    463     }
    464 
    465     // for debugging purpose
    466     if (outputByPoc->pictureOrder != 0 && outputByPoc->pictureOrder < mNextOutputPOC) {
    467         ETRACE("Output POC is not incremental, expected %d, actual %d", mNextOutputPOC, outputByPoc->pictureOrder);
    468         //gaps_in_frame_num_value_allowed_flag is not currently supported
    469     }
    470 
    471     mNextOutputPOC = outputByPoc->pictureOrder + 1;
    472 
    473     return outputByPoc;
    474 }
    475 #else
    476 VideoSurfaceBuffer* VideoDecoderBase::findOutputByPoc(bool draining) {
    477     VideoSurfaceBuffer *output = NULL;
    478     VideoSurfaceBuffer *p = mOutputHead;
    479     int32_t count = 0;
    480     int32_t poc = MAXIMUM_POC;
    481     VideoSurfaceBuffer *outputleastpoc = mOutputHead;
    482     do {
    483         count++;
    484         if (p->pictureOrder == 0) {
    485             // any picture before this POC (new IDR) must be output
    486             if (output == NULL) {
    487                 mNextOutputPOC = MINIMUM_POC;
    488                 // looking for any POC with negative value
    489             } else {
    490                 mNextOutputPOC = output->pictureOrder + 1;
    491                 break;
    492             }
    493         }
    494         if (p->pictureOrder < poc && p->pictureOrder >= mNextOutputPOC) {
    495             // this POC meets ouput criteria.
    496             poc = p->pictureOrder;
    497             output = p;
    498             outputleastpoc = p;
    499         }
    500         if (poc == mNextOutputPOC || count == mOutputWindowSize) {
    501             if (output != NULL) {
    502                 // this indicates two cases:
    503                 // 1) the next output POC is found.
    504                 // 2) output queue is full and there is at least one buffer meeting the output criteria.
    505                 mNextOutputPOC = output->pictureOrder + 1;
    506                 break;
    507             } else {
    508                 // this indicates output queue is full and no buffer in the queue meets the output criteria
    509                 // restart processing as queue is FULL and output criteria is changed. (next output POC is 0)
    510                 mNextOutputPOC = MINIMUM_POC;
    511                 count = 0;
    512                 poc = MAXIMUM_POC;
    513                 p = mOutputHead;
    514                 continue;
    515             }
    516         }
    517         if (p->next == NULL) {
    518             output = NULL;
    519         }
    520 
    521         p = p->next;
    522     } while (p != NULL);
    523 
    524     if (draining == true && output == NULL) {
    525         output = outputleastpoc;
    526     }
    527 
    528     return output;
    529 }
    530 #endif
    531 
    532 bool VideoDecoderBase::checkBufferAvail(void) {
    533     if (!mInitialized) {
    534         if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) == 0) {
    535             return true;
    536         }
    537         for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
    538             if (mSignalBufferPre[i] != NULL) {
    539                 return true;
    540             }
    541         }
    542         return false;
    543     }
    544     // check whether there is buffer available for decoding
    545     // TODO: check frame being referenced for frame skipping
    546     VideoSurfaceBuffer *buffer = NULL;
    547     for (int32_t i = 0; i < mNumSurfaces; i++) {
    548         buffer = mSurfaceBuffers + i;
    549 
    550         if (buffer->asReferernce == false &&
    551             buffer->renderBuffer.renderDone == true) {
    552             querySurfaceRenderStatus(buffer);
    553             if (buffer->renderBuffer.driverRenderDone == true)
    554                 return true;
    555         }
    556      }
    557     return false;
    558 }
    559 
    560 Decode_Status VideoDecoderBase::acquireSurfaceBuffer(void) {
    561     if (mVAStarted == false) {
    562         return DECODE_FAIL;
    563     }
    564 
    565     if (mAcquiredBuffer != NULL) {
    566         ETRACE("mAcquiredBuffer is not NULL. Implementation bug.");
    567         return DECODE_FAIL;
    568     }
    569 
    570     int nextAcquire = mSurfaceAcquirePos;
    571     VideoSurfaceBuffer *acquiredBuffer = NULL;
    572     bool acquired = false;
    573 
    574     while (acquired == false) {
    575         acquiredBuffer = mSurfaceBuffers + nextAcquire;
    576 
    577         querySurfaceRenderStatus(acquiredBuffer);
    578 
    579         if (acquiredBuffer->asReferernce == false && acquiredBuffer->renderBuffer.renderDone == true && acquiredBuffer->renderBuffer.driverRenderDone == true) {
    580             // this is potential buffer for acquisition. Check if it is referenced by other surface for frame skipping
    581             VideoSurfaceBuffer *temp;
    582             acquired = true;
    583             for (int i = 0; i < mNumSurfaces; i++) {
    584                 if (i == nextAcquire) {
    585                     continue;
    586                 }
    587                 temp = mSurfaceBuffers + i;
    588                 // use mSurfaces[nextAcquire] instead of acquiredBuffer->renderBuffer.surface as its the actual surface to use.
    589                 if (temp->renderBuffer.surface == mSurfaces[nextAcquire] &&
    590                     temp->renderBuffer.renderDone == false) {
    591                     ITRACE("Surface is referenced by other surface buffer.");
    592                     acquired = false;
    593                     break;
    594                 }
    595             }
    596         }
    597         if (acquired) {
    598             break;
    599         }
    600         nextAcquire++;
    601         if (nextAcquire == mNumSurfaces) {
    602             nextAcquire = 0;
    603         }
    604         if (nextAcquire == mSurfaceAcquirePos) {
    605             return DECODE_NO_SURFACE;
    606         }
    607     }
    608 
    609     if (acquired == false) {
    610         return DECODE_NO_SURFACE;
    611     }
    612 
    613     mAcquiredBuffer = acquiredBuffer;
    614     mSurfaceAcquirePos = nextAcquire;
    615 
    616     // set surface again as surface maybe reset by skipped frame.
    617     // skipped frame is a "non-coded frame" and decoder needs to duplicate the previous reference frame as the output.
    618     mAcquiredBuffer->renderBuffer.surface = mSurfaces[mSurfaceAcquirePos];
    619     if (mSurfaceUserPtr && mAcquiredBuffer->mappedData) {
    620         mAcquiredBuffer->mappedData->data = mSurfaceUserPtr[mSurfaceAcquirePos];
    621     }
    622     mAcquiredBuffer->renderBuffer.timeStamp = INVALID_PTS;
    623     mAcquiredBuffer->renderBuffer.display = mVADisplay;
    624     mAcquiredBuffer->renderBuffer.flag = 0;
    625     mAcquiredBuffer->renderBuffer.renderDone = false;
    626     mAcquiredBuffer->asReferernce = false;
    627     mAcquiredBuffer->renderBuffer.errBuf.errorNumber = 0;
    628     mAcquiredBuffer->renderBuffer.errBuf.timeStamp = INVALID_PTS;
    629 
    630     return DECODE_SUCCESS;
    631 }
    632 
    633 Decode_Status VideoDecoderBase::outputSurfaceBuffer(void) {
    634     Decode_Status status;
    635     if (mAcquiredBuffer == NULL) {
    636         ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
    637         return DECODE_FAIL;
    638     }
    639 
    640     if (mRawOutput) {
    641         status = getRawDataFromSurface();
    642         CHECK_STATUS();
    643     }
    644 
    645     // frame is successfly decoded to the current surface,  it is ready for output
    646     if (mShowFrame) {
    647         mAcquiredBuffer->renderBuffer.renderDone = false;
    648     } else {
    649         mAcquiredBuffer->renderBuffer.renderDone = true;
    650     }
    651 
    652     // decoder must set "asReference and referenceFrame" flags properly
    653 
    654     // update reference frames
    655     if (mAcquiredBuffer->referenceFrame) {
    656         if (mManageReference) {
    657             // managing reference for MPEG4/H.263/WMV.
    658             // AVC should manage reference frame in a different way
    659             if (mForwardReference != NULL) {
    660                 // this foward reference is no longer needed
    661                 mForwardReference->asReferernce = false;
    662             }
    663             // Forware reference for either P or B frame prediction
    664             mForwardReference = mLastReference;
    665             mAcquiredBuffer->asReferernce = true;
    666         }
    667 
    668         // the last reference frame.
    669         mLastReference = mAcquiredBuffer;
    670     }
    671     // add to the output list
    672     if (mShowFrame) {
    673         if (mOutputHead == NULL) {
    674             mOutputHead = mAcquiredBuffer;
    675         } else {
    676             mOutputTail->next = mAcquiredBuffer;
    677         }
    678         mOutputTail = mAcquiredBuffer;
    679         mOutputTail->next = NULL;
    680     }
    681 
    682     //VTRACE("Pushing POC %d to queue (pts = %.2f)", mAcquiredBuffer->pictureOrder, mAcquiredBuffer->renderBuffer.timeStamp/1E6);
    683 
    684     mAcquiredBuffer = NULL;
    685     mSurfaceAcquirePos = (mSurfaceAcquirePos  + 1 ) % mNumSurfaces;
    686     return DECODE_SUCCESS;
    687 }
    688 
    689 Decode_Status VideoDecoderBase::releaseSurfaceBuffer(void) {
    690     if (mAcquiredBuffer == NULL) {
    691         // this is harmless error
    692         return DECODE_SUCCESS;
    693     }
    694 
    695     // frame is not decoded to the acquired buffer, current surface is invalid, and can't be output.
    696     mAcquiredBuffer->asReferernce = false;
    697     mAcquiredBuffer->renderBuffer.renderDone = true;
    698     mAcquiredBuffer = NULL;
    699     return DECODE_SUCCESS;
    700 }
    701 
    702 void VideoDecoderBase::flushSurfaceBuffers(void) {
    703     endDecodingFrame(true);
    704     VideoSurfaceBuffer *p = NULL;
    705     while (mOutputHead) {
    706         mOutputHead->renderBuffer.renderDone = true;
    707         p = mOutputHead;
    708         mOutputHead = mOutputHead->next;
    709         p->next = NULL;
    710     }
    711     mOutputHead = NULL;
    712     mOutputTail = NULL;
    713 }
    714 
    715 Decode_Status VideoDecoderBase::endDecodingFrame(bool dropFrame) {
    716     Decode_Status status = DECODE_SUCCESS;
    717     VAStatus vaStatus;
    718 
    719     if (mDecodingFrame == false) {
    720         if (mAcquiredBuffer != NULL) {
    721             //ETRACE("mAcquiredBuffer is not NULL. Implementation bug.");
    722             releaseSurfaceBuffer();
    723             status = DECODE_FAIL;
    724         }
    725         return status;
    726     }
    727     // return through exit label to reset mDecodingFrame
    728     if (mAcquiredBuffer == NULL) {
    729         ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
    730         status = DECODE_FAIL;
    731         goto exit;
    732     }
    733 
    734     vaStatus = vaEndPicture(mVADisplay, mVAContext);
    735     if (vaStatus != VA_STATUS_SUCCESS) {
    736         releaseSurfaceBuffer();
    737         ETRACE("vaEndPicture failed. vaStatus = %d", vaStatus);
    738         status = DECODE_DRIVER_FAIL;
    739         goto exit;
    740     }
    741 
    742     if (dropFrame) {
    743         // we are asked to drop this decoded picture
    744         VTRACE("Frame dropped in endDecodingFrame");
    745         vaStatus = vaSyncSurface(mVADisplay, mAcquiredBuffer->renderBuffer.surface);
    746         releaseSurfaceBuffer();
    747         goto exit;
    748     }
    749     status = outputSurfaceBuffer();
    750     // fall through
    751 exit:
    752     mDecodingFrame = false;
    753     return status;
    754 }
    755 
    756 
    757 Decode_Status VideoDecoderBase::setupVA(uint32_t numSurface, VAProfile profile, uint32_t numExtraSurface) {
    758     VAStatus vaStatus = VA_STATUS_SUCCESS;
    759     Decode_Status status;
    760     VAConfigAttrib attrib;
    761 
    762     if (mVAStarted) {
    763         return DECODE_SUCCESS;
    764     }
    765 
    766     mRotationDegrees = 0;
    767     if (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER){
    768 #ifdef TARGET_HAS_ISV
    769         if (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber - mConfigBuffer.vppBufferNum)
    770 #else
    771         if (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber)
    772 #endif
    773             return DECODE_FORMAT_CHANGE;
    774 
    775         numSurface = mConfigBuffer.surfaceNumber;
    776         // if format has been changed in USE_NATIVE_GRAPHIC_BUFFER mode,
    777         // we can not setupVA here when the graphic buffer resolution is smaller than the resolution decoder really needs
    778         if (mSizeChanged) {
    779             if (mVideoFormatInfo.surfaceWidth < mVideoFormatInfo.width || mVideoFormatInfo.surfaceHeight < mVideoFormatInfo.height) {
    780                 mSizeChanged = false;
    781                 return DECODE_FORMAT_CHANGE;
    782             }
    783         }
    784     }
    785 
    786     // TODO: validate profile
    787     if (numSurface == 0) {
    788         return DECODE_FAIL;
    789     }
    790 
    791     if (mConfigBuffer.flag & HAS_MINIMUM_SURFACE_NUMBER) {
    792         if (numSurface < mConfigBuffer.surfaceNumber) {
    793             WTRACE("surface to allocated %d is less than minimum number required %d",
    794                     numSurface, mConfigBuffer.surfaceNumber);
    795             numSurface = mConfigBuffer.surfaceNumber;
    796         }
    797     }
    798 
    799     if (mVADisplay != NULL) {
    800         ETRACE("VA is partially started.");
    801         return DECODE_FAIL;
    802     }
    803 
    804     // Display is defined as "unsigned int"
    805 #ifndef USE_HYBRID_DRIVER
    806     mDisplay = new Display;
    807     *mDisplay = ANDROID_DISPLAY_HANDLE;
    808 #else
    809     if (profile >= VAProfileH264Baseline && profile <= VAProfileVC1Advanced) {
    810         ITRACE("Using GEN driver");
    811         mDisplay = "libva_driver_name=i965";
    812         mUseGEN = true;
    813     } else {
    814         ITRACE("Using PVR driver");
    815         mDisplay = "libva_driver_name=pvr";
    816         mUseGEN = false;
    817     }
    818 
    819 #endif
    820     mVADisplay = vaGetDisplay(mDisplay);
    821     if (mVADisplay == NULL) {
    822         ETRACE("vaGetDisplay failed.");
    823         return DECODE_DRIVER_FAIL;
    824     }
    825 
    826     int majorVersion, minorVersion;
    827     vaStatus = vaInitialize(mVADisplay, &majorVersion, &minorVersion);
    828     CHECK_VA_STATUS("vaInitialize");
    829 
    830     if ((int32_t)profile != VAProfileSoftwareDecoding) {
    831 
    832         status = checkHardwareCapability();
    833         CHECK_STATUS("checkHardwareCapability");
    834 
    835 #if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
    836         status = getCodecSpecificConfigs(profile, &mVAConfig);
    837         CHECK_STATUS("getCodecSpecificAttributes");
    838 #else
    839         //We are requesting RT attributes
    840         attrib.type = VAConfigAttribRTFormat;
    841         attrib.value = VA_RT_FORMAT_YUV420;
    842 
    843         vaStatus = vaCreateConfig(
    844                 mVADisplay,
    845                 profile,
    846                 VAEntrypointVLD,
    847                 &attrib,
    848                 1,
    849                 &mVAConfig);
    850         CHECK_VA_STATUS("vaCreateConfig");
    851 #endif
    852     }
    853 
    854     mNumSurfaces = numSurface;
    855     mNumExtraSurfaces = numExtraSurface;
    856     mSurfaces = new VASurfaceID [mNumSurfaces + mNumExtraSurfaces];
    857     mExtraSurfaces = mSurfaces + mNumSurfaces;
    858     if (mSurfaces == NULL) {
    859         return DECODE_MEMORY_FAIL;
    860     }
    861 
    862     setRenderRect();
    863 
    864     int32_t format = VA_RT_FORMAT_YUV420;
    865     if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION) {
    866 #ifndef USE_AVC_SHORT_FORMAT
    867         format |= VA_RT_FORMAT_PROTECTED;
    868         WTRACE("Surface is protected.");
    869 #endif
    870     }
    871     if (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) {
    872         VASurfaceAttrib attribs[2];
    873         mVASurfaceAttrib = new VASurfaceAttribExternalBuffers;
    874         if (mVASurfaceAttrib == NULL) {
    875             return DECODE_MEMORY_FAIL;
    876         }
    877 
    878         mVASurfaceAttrib->buffers= (unsigned long *)malloc(sizeof(unsigned long)*mNumSurfaces);
    879         if (mVASurfaceAttrib->buffers == NULL) {
    880             return DECODE_MEMORY_FAIL;
    881         }
    882         mVASurfaceAttrib->num_buffers = mNumSurfaces;
    883         mVASurfaceAttrib->pixel_format = VA_FOURCC_NV12;
    884         mVASurfaceAttrib->width = mVideoFormatInfo.surfaceWidth;
    885         mVASurfaceAttrib->height = mVideoFormatInfo.surfaceHeight;
    886         mVASurfaceAttrib->data_size = mConfigBuffer.graphicBufferStride * mVideoFormatInfo.surfaceHeight * 1.5;
    887         mVASurfaceAttrib->num_planes = 2;
    888         mVASurfaceAttrib->pitches[0] = mConfigBuffer.graphicBufferStride;
    889         mVASurfaceAttrib->pitches[1] = mConfigBuffer.graphicBufferStride;
    890         mVASurfaceAttrib->pitches[2] = 0;
    891         mVASurfaceAttrib->pitches[3] = 0;
    892         mVASurfaceAttrib->offsets[0] = 0;
    893         mVASurfaceAttrib->offsets[1] = mConfigBuffer.graphicBufferStride * mVideoFormatInfo.surfaceHeight;
    894         mVASurfaceAttrib->offsets[2] = 0;
    895         mVASurfaceAttrib->offsets[3] = 0;
    896         mVASurfaceAttrib->private_data = (void *)mConfigBuffer.nativeWindow;
    897         mVASurfaceAttrib->flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
    898         if (mConfigBuffer.flag & USE_TILING_MEMORY)
    899             mVASurfaceAttrib->flags |= VA_SURFACE_EXTBUF_DESC_ENABLE_TILING;
    900 
    901         for (int i = 0; i < mNumSurfaces; i++) {
    902             mVASurfaceAttrib->buffers[i] = (unsigned long)mConfigBuffer.graphicBufferHandler[i];
    903         }
    904 
    905         attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
    906         attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
    907         attribs[0].value.type = VAGenericValueTypeInteger;
    908         attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
    909 
    910         attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
    911         attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
    912         attribs[1].value.type = VAGenericValueTypePointer;
    913         attribs[1].value.value.p = (void *)mVASurfaceAttrib;
    914 
    915         vaStatus = vaCreateSurfaces(
    916             mVADisplay,
    917             format,
    918             mVideoFormatInfo.surfaceWidth,
    919             mVideoFormatInfo.surfaceHeight,
    920             mSurfaces,
    921             mNumSurfaces,
    922             attribs,
    923             2);
    924 
    925     } else {
    926         vaStatus = vaCreateSurfaces(
    927             mVADisplay,
    928             format,
    929             mVideoFormatInfo.width,
    930             mVideoFormatInfo.height,
    931             mSurfaces,
    932             mNumSurfaces,
    933             NULL,
    934             0);
    935         mVideoFormatInfo.surfaceWidth = mVideoFormatInfo.width;
    936         mVideoFormatInfo.surfaceHeight = mVideoFormatInfo.height;
    937     }
    938     CHECK_VA_STATUS("vaCreateSurfaces");
    939 
    940     if (mNumExtraSurfaces != 0) {
    941         vaStatus = vaCreateSurfaces(
    942             mVADisplay,
    943             format,
    944             mVideoFormatInfo.surfaceWidth,
    945             mVideoFormatInfo.surfaceHeight,
    946             mExtraSurfaces,
    947             mNumExtraSurfaces,
    948             NULL,
    949             0);
    950         CHECK_VA_STATUS("vaCreateSurfaces");
    951     }
    952 
    953     mVideoFormatInfo.surfaceNumber = mNumSurfaces;
    954     mVideoFormatInfo.ctxSurfaces = mSurfaces;
    955 
    956     if ((int32_t)profile != VAProfileSoftwareDecoding) {
    957         vaStatus = vaCreateContext(
    958                 mVADisplay,
    959                 mVAConfig,
    960                 mVideoFormatInfo.surfaceWidth,
    961                 mVideoFormatInfo.surfaceHeight,
    962                 0,
    963                 mSurfaces,
    964                 mNumSurfaces + mNumExtraSurfaces,
    965                 &mVAContext);
    966         CHECK_VA_STATUS("vaCreateContext");
    967     }
    968 
    969     mSurfaceBuffers = new VideoSurfaceBuffer [mNumSurfaces];
    970     if (mSurfaceBuffers == NULL) {
    971         return DECODE_MEMORY_FAIL;
    972     }
    973     initSurfaceBuffer(true);
    974 
    975     if ((int32_t)profile == VAProfileSoftwareDecoding) {
    976         // derive user pointer from surface for direct access
    977         status = mapSurface();
    978         CHECK_STATUS("mapSurface")
    979     }
    980 
    981     setRotationDegrees(mConfigBuffer.rotationDegrees);
    982 
    983     mVAStarted = true;
    984     return DECODE_SUCCESS;
    985 }
    986 
    987 Decode_Status VideoDecoderBase::terminateVA(void) {
    988     mSignalBufferSize = 0;
    989     for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) {
    990          mSignalBufferPre[i] = NULL;
    991     }
    992 
    993     if (mVAStarted == false) {
    994         // VA hasn't been started yet
    995         return DECODE_SUCCESS;
    996     }
    997 
    998     if (mSurfaceBuffers) {
    999         for (int32_t i = 0; i < mNumSurfaces; i++) {
   1000             if (mSurfaceBuffers[i].renderBuffer.rawData) {
   1001                 if (mSurfaceBuffers[i].renderBuffer.rawData->data) {
   1002                     delete [] mSurfaceBuffers[i].renderBuffer.rawData->data;
   1003                 }
   1004                 delete mSurfaceBuffers[i].renderBuffer.rawData;
   1005             }
   1006             if (mSurfaceBuffers[i].mappedData) {
   1007                 // don't  delete data pointer as it is mapped from surface
   1008                 delete mSurfaceBuffers[i].mappedData;
   1009             }
   1010         }
   1011         delete [] mSurfaceBuffers;
   1012         mSurfaceBuffers = NULL;
   1013     }
   1014 
   1015     if (mVASurfaceAttrib) {
   1016         if (mVASurfaceAttrib->buffers) free(mVASurfaceAttrib->buffers);
   1017         delete mVASurfaceAttrib;
   1018         mVASurfaceAttrib = NULL;
   1019     }
   1020 
   1021 
   1022     if (mSurfaceUserPtr) {
   1023         delete [] mSurfaceUserPtr;
   1024         mSurfaceUserPtr = NULL;
   1025     }
   1026 
   1027     if (mSurfaces)
   1028     {
   1029         vaDestroySurfaces(mVADisplay, mSurfaces, mNumSurfaces + mNumExtraSurfaces);
   1030         delete [] mSurfaces;
   1031         mSurfaces = NULL;
   1032     }
   1033 
   1034     if (mVAContext != VA_INVALID_ID) {
   1035          vaDestroyContext(mVADisplay, mVAContext);
   1036          mVAContext = VA_INVALID_ID;
   1037     }
   1038 
   1039     if (mVAConfig != VA_INVALID_ID) {
   1040         vaDestroyConfig(mVADisplay, mVAConfig);
   1041         mVAConfig = VA_INVALID_ID;
   1042     }
   1043 
   1044     if (mVADisplay) {
   1045         vaTerminate(mVADisplay);
   1046         mVADisplay = NULL;
   1047     }
   1048 
   1049     if (mDisplay) {
   1050 #ifndef USE_HYBRID_DRIVER
   1051         delete mDisplay;
   1052 #endif
   1053         mDisplay = NULL;
   1054     }
   1055 
   1056     mVAStarted = false;
   1057     mInitialized = false;
   1058     mErrReportEnabled = false;
   1059     return DECODE_SUCCESS;
   1060 }
   1061 
   1062 Decode_Status VideoDecoderBase::parseBuffer(uint8_t *buffer, int32_t size, bool config, void** vbpData) {
   1063      // DON'T check if mVAStarted == true
   1064     if (mParserHandle == NULL) {
   1065         return DECODE_NO_PARSER;
   1066     }
   1067 
   1068     uint32_t vbpStatus;
   1069     if (buffer == NULL || size <= 0) {
   1070         return DECODE_INVALID_DATA;
   1071     }
   1072 
   1073     uint8_t configFlag = config ? 1 : 0;
   1074     vbpStatus = mParserParse(mParserHandle, buffer, size, configFlag);
   1075     CHECK_VBP_STATUS("vbp_parse");
   1076 
   1077     vbpStatus = mParserQuery(mParserHandle, vbpData);
   1078     CHECK_VBP_STATUS("vbp_query");
   1079 
   1080     return DECODE_SUCCESS;
   1081 }
   1082 
   1083 
   1084 
   1085 Decode_Status VideoDecoderBase::mapSurface(void) {
   1086     VAStatus vaStatus = VA_STATUS_SUCCESS;
   1087     VAImage image;
   1088     uint8_t *userPtr;
   1089     mSurfaceUserPtr = new uint8_t* [mNumSurfaces];
   1090     if (mSurfaceUserPtr == NULL) {
   1091         return DECODE_MEMORY_FAIL;
   1092     }
   1093 
   1094     for (int32_t i = 0; i< mNumSurfaces; i++) {
   1095         vaStatus = vaDeriveImage(mVADisplay, mSurfaces[i], &image);
   1096         CHECK_VA_STATUS("vaDeriveImage");
   1097         vaStatus = vaMapBuffer(mVADisplay, image.buf, (void**)&userPtr);
   1098         CHECK_VA_STATUS("vaMapBuffer");
   1099         mSurfaceUserPtr[i] = userPtr;
   1100         mSurfaceBuffers[i].mappedData = new VideoFrameRawData;
   1101         if (mSurfaceBuffers[i].mappedData == NULL) {
   1102             return DECODE_MEMORY_FAIL;
   1103         }
   1104         mSurfaceBuffers[i].mappedData->own = false; // derived from surface so can't be released
   1105         mSurfaceBuffers[i].mappedData->data = NULL;  // specified during acquireSurfaceBuffer
   1106         mSurfaceBuffers[i].mappedData->fourcc = image.format.fourcc;
   1107         mSurfaceBuffers[i].mappedData->width = mVideoFormatInfo.width;
   1108         mSurfaceBuffers[i].mappedData->height = mVideoFormatInfo.height;
   1109         mSurfaceBuffers[i].mappedData->size = image.data_size;
   1110         for (int pi = 0; pi < 3; pi++) {
   1111             mSurfaceBuffers[i].mappedData->pitch[pi] = image.pitches[pi];
   1112             mSurfaceBuffers[i].mappedData->offset[pi] = image.offsets[pi];
   1113         }
   1114         // debug information
   1115         if (image.pitches[0] != image.pitches[1] ||
   1116             image.width != mVideoFormatInfo.width ||
   1117             image.height != mVideoFormatInfo.height ||
   1118             image.offsets[0] != 0) {
   1119             WTRACE("Unexpected VAImage format, w = %d, h = %d, offset = %d", image.width, image.height, image.offsets[0]);
   1120         }
   1121         // TODO: do we need to unmap buffer?
   1122         //vaStatus = vaUnmapBuffer(mVADisplay, image.buf);
   1123         //CHECK_VA_STATUS("vaMapBuffer");
   1124         vaStatus = vaDestroyImage(mVADisplay,image.image_id);
   1125         CHECK_VA_STATUS("vaDestroyImage");
   1126 
   1127     }
   1128     return DECODE_SUCCESS;
   1129 }
   1130 
   1131 Decode_Status VideoDecoderBase::getRawDataFromSurface(VideoRenderBuffer *renderBuffer, uint8_t *pRawData, uint32_t *pSize, bool internal) {
   1132     if (internal) {
   1133         if (mAcquiredBuffer == NULL) {
   1134             return DECODE_FAIL;
   1135         }
   1136         renderBuffer = &(mAcquiredBuffer->renderBuffer);
   1137     }
   1138 
   1139     VAStatus vaStatus;
   1140     VAImageFormat imageFormat;
   1141     VAImage vaImage;
   1142     vaStatus = vaSyncSurface(renderBuffer->display, renderBuffer->surface);
   1143     CHECK_VA_STATUS("vaSyncSurface");
   1144 
   1145     vaStatus = vaDeriveImage(renderBuffer->display, renderBuffer->surface, &vaImage);
   1146     CHECK_VA_STATUS("vaDeriveImage");
   1147 
   1148     void *pBuf = NULL;
   1149     vaStatus = vaMapBuffer(renderBuffer->display, vaImage.buf, &pBuf);
   1150     CHECK_VA_STATUS("vaMapBuffer");
   1151 
   1152 
   1153     // size in NV12 format
   1154     uint32_t cropWidth = mVideoFormatInfo.width - (mVideoFormatInfo.cropLeft + mVideoFormatInfo.cropRight);
   1155     uint32_t cropHeight = mVideoFormatInfo.height - (mVideoFormatInfo.cropBottom + mVideoFormatInfo.cropTop);
   1156     int32_t size = cropWidth  * cropHeight * 3 / 2;
   1157 
   1158     if (internal) {
   1159         VideoFrameRawData *rawData = NULL;
   1160         if (renderBuffer->rawData == NULL) {
   1161             rawData = new VideoFrameRawData;
   1162             if (rawData == NULL) {
   1163                 return DECODE_MEMORY_FAIL;
   1164             }
   1165             memset(rawData, 0, sizeof(VideoFrameRawData));
   1166             renderBuffer->rawData = rawData;
   1167         } else {
   1168             rawData = renderBuffer->rawData;
   1169         }
   1170 
   1171         if (rawData->data != NULL && rawData->size != size) {
   1172             delete [] rawData->data;
   1173             rawData->data = NULL;
   1174             rawData->size = 0;
   1175         }
   1176         if (rawData->data == NULL) {
   1177             rawData->data = new uint8_t [size];
   1178             if (rawData->data == NULL) {
   1179                 return DECODE_MEMORY_FAIL;
   1180             }
   1181         }
   1182 
   1183         rawData->own = true; // allocated by this library
   1184         rawData->width = cropWidth;
   1185         rawData->height = cropHeight;
   1186         rawData->pitch[0] = cropWidth;
   1187         rawData->pitch[1] = cropWidth;
   1188         rawData->pitch[2] = 0;  // interleaved U/V, two planes
   1189         rawData->offset[0] = 0;
   1190         rawData->offset[1] = cropWidth * cropHeight;
   1191         rawData->offset[2] = cropWidth * cropHeight * 3 / 2;
   1192         rawData->size = size;
   1193         rawData->fourcc = 'NV12';
   1194 
   1195         pRawData = rawData->data;
   1196     } else {
   1197         *pSize = size;
   1198     }
   1199 
   1200     if (size == (int32_t)vaImage.data_size) {
   1201 #ifdef  __SSE4_1__
   1202         stream_memcpy(pRawData, pBuf, size);
   1203 #else
   1204         memcpy(pRawData, pBuf, size);
   1205 #endif
   1206     } else {
   1207         // copy Y data
   1208         uint8_t *src = (uint8_t*)pBuf;
   1209         uint8_t *dst = pRawData;
   1210         uint32_t row = 0;
   1211         for (row = 0; row < cropHeight; row++) {
   1212 #ifdef  __SSE4_1__
   1213             stream_memcpy(dst, src, cropWidth);
   1214 #else
   1215             memcpy(dst, src, cropWidth);
   1216 #endif
   1217             dst += cropWidth;
   1218             src += vaImage.pitches[0];
   1219         }
   1220         // copy interleaved V and  U data
   1221         src = (uint8_t*)pBuf + vaImage.offsets[1];
   1222         for (row = 0; row < cropHeight / 2; row++) {
   1223 #ifdef  __SSE4_1__
   1224             stream_memcpy(dst, src, cropWidth);
   1225 #else
   1226             memcpy(dst, src, cropWidth);
   1227 #endif
   1228             dst += cropWidth;
   1229             src += vaImage.pitches[1];
   1230         }
   1231     }
   1232 
   1233     vaStatus = vaUnmapBuffer(renderBuffer->display, vaImage.buf);
   1234     CHECK_VA_STATUS("vaUnmapBuffer");
   1235 
   1236     vaStatus = vaDestroyImage(renderBuffer->display, vaImage.image_id);
   1237     CHECK_VA_STATUS("vaDestroyImage");
   1238 
   1239     return DECODE_SUCCESS;
   1240 }
   1241 
   1242 void VideoDecoderBase::initSurfaceBuffer(bool reset) {
   1243     bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
   1244     if (useGraphicBuffer && reset) {
   1245         pthread_mutex_lock(&mLock);
   1246     }
   1247     for (int32_t i = 0; i < mNumSurfaces; i++) {
   1248         mSurfaceBuffers[i].renderBuffer.display = mVADisplay;
   1249         mSurfaceBuffers[i].renderBuffer.surface = VA_INVALID_SURFACE;  // set in acquireSurfaceBuffer
   1250         mSurfaceBuffers[i].renderBuffer.flag = 0;
   1251         mSurfaceBuffers[i].renderBuffer.scanFormat = VA_FRAME_PICTURE;
   1252         mSurfaceBuffers[i].renderBuffer.timeStamp = 0;
   1253         mSurfaceBuffers[i].referenceFrame = false;
   1254         mSurfaceBuffers[i].asReferernce= false;
   1255         mSurfaceBuffers[i].pictureOrder = 0;
   1256         mSurfaceBuffers[i].next = NULL;
   1257         if (reset == true) {
   1258             mSurfaceBuffers[i].renderBuffer.rawData = NULL;
   1259             mSurfaceBuffers[i].mappedData = NULL;
   1260         }
   1261         if (useGraphicBuffer) {
   1262             if (reset) {
   1263                mSurfaceBuffers[i].renderBuffer.graphicBufferHandle = mConfigBuffer.graphicBufferHandler[i];
   1264                mSurfaceBuffers[i].renderBuffer.renderDone = false; //default false
   1265                for (uint32_t j = 0; j < mSignalBufferSize; j++) {
   1266                    if(mSignalBufferPre[j] != NULL && mSignalBufferPre[j] == mSurfaceBuffers[i].renderBuffer.graphicBufferHandle) {
   1267                       mSurfaceBuffers[i].renderBuffer.renderDone = true;
   1268                       VTRACE("initSurfaceBuffer set renderDone = true index = %d", i);
   1269                       mSignalBufferPre[j] = NULL;
   1270                       break;
   1271                    }
   1272                }
   1273             } else {
   1274                mSurfaceBuffers[i].renderBuffer.renderDone = false;
   1275             }
   1276         } else {
   1277             mSurfaceBuffers[i].renderBuffer.graphicBufferHandle = NULL;
   1278             mSurfaceBuffers[i].renderBuffer.renderDone = true;
   1279         }
   1280         mSurfaceBuffers[i].renderBuffer.graphicBufferIndex = i;
   1281     }
   1282 
   1283     if (useGraphicBuffer && reset) {
   1284         mInitialized = true;
   1285         mSignalBufferSize = 0;
   1286         pthread_mutex_unlock(&mLock);
   1287     }
   1288 }
   1289 
   1290 Decode_Status VideoDecoderBase::signalRenderDone(void * graphichandler) {
   1291     if (graphichandler == NULL) {
   1292         return DECODE_SUCCESS;
   1293     }
   1294     pthread_mutex_lock(&mLock);
   1295     int i = 0;
   1296     if (!mInitialized) {
   1297         if (mSignalBufferSize >= MAX_GRAPHIC_BUFFER_NUM) {
   1298             pthread_mutex_unlock(&mLock);
   1299             return DECODE_INVALID_DATA;
   1300         }
   1301         mSignalBufferPre[mSignalBufferSize++] = graphichandler;
   1302         VTRACE("SignalRenderDoneFlag mInitialized = false graphichandler = %p, mSignalBufferSize = %d", graphichandler, mSignalBufferSize);
   1303     } else {
   1304         if (!(mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) {
   1305             pthread_mutex_unlock(&mLock);
   1306             return DECODE_SUCCESS;
   1307         }
   1308         for (i = 0; i < mNumSurfaces; i++) {
   1309             if (mSurfaceBuffers[i].renderBuffer.graphicBufferHandle == graphichandler) {
   1310                 mSurfaceBuffers[i].renderBuffer.renderDone = true;
   1311                 VTRACE("SignalRenderDoneFlag mInitialized = true index = %d", i);
   1312                break;
   1313            }
   1314         }
   1315     }
   1316     pthread_mutex_unlock(&mLock);
   1317 
   1318     return DECODE_SUCCESS;
   1319 
   1320 }
   1321 
   1322 void VideoDecoderBase::querySurfaceRenderStatus(VideoSurfaceBuffer* surface) {
   1323     VASurfaceStatus surfStat = VASurfaceReady;
   1324     VAStatus    vaStat = VA_STATUS_SUCCESS;
   1325 
   1326     if (!surface) {
   1327         LOGW("SurfaceBuffer not ready yet");
   1328         return;
   1329     }
   1330     surface->renderBuffer.driverRenderDone = true;
   1331 
   1332 #ifndef USE_GEN_HW
   1333     if (surface->renderBuffer.surface != VA_INVALID_SURFACE &&
   1334        (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) {
   1335 
   1336         vaStat = vaQuerySurfaceStatus(mVADisplay, surface->renderBuffer.surface, &surfStat);
   1337 
   1338         if ((vaStat == VA_STATUS_SUCCESS) && (surfStat != VASurfaceReady))
   1339             surface->renderBuffer.driverRenderDone = false;
   1340 
   1341     }
   1342 #endif
   1343 
   1344 }
   1345 
   1346 // This function should be called before start() to load different type of parsers
   1347 #if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
   1348 Decode_Status VideoDecoderBase::setParserType(_vbp_parser_type type) {
   1349     if ((int32_t)type != VBP_INVALID) {
   1350         ITRACE("Parser Type = %d", (int32_t)type);
   1351         mParserType = type;
   1352         return DECODE_SUCCESS;
   1353     } else {
   1354         ETRACE("Invalid parser type = %d", (int32_t)type);
   1355         return DECODE_NO_PARSER;
   1356     }
   1357 }
   1358 
   1359 Decode_Status VideoDecoderBase::updateBuffer(uint8_t *buffer, int32_t size, void** vbpData) {
   1360     if (mParserHandle == NULL) {
   1361         return DECODE_NO_PARSER;
   1362     }
   1363 
   1364     uint32_t vbpStatus;
   1365     if (buffer == NULL || size <= 0) {
   1366         return DECODE_INVALID_DATA;
   1367     }
   1368 
   1369     vbpStatus = mParserUpdate(mParserHandle, buffer, size, vbpData);
   1370     CHECK_VBP_STATUS("vbp_update");
   1371 
   1372     return DECODE_SUCCESS;
   1373 }
   1374 
   1375 Decode_Status VideoDecoderBase::queryBuffer(void** vbpData) {
   1376     if (mParserHandle == NULL) {
   1377         return DECODE_NO_PARSER;
   1378     }
   1379 
   1380     uint32_t vbpStatus;
   1381     vbpStatus = mParserQuery(mParserHandle, vbpData);
   1382     CHECK_VBP_STATUS("vbp_query");
   1383 
   1384     return DECODE_SUCCESS;
   1385 }
   1386 
   1387 Decode_Status VideoDecoderBase::getCodecSpecificConfigs(VAProfile profile, VAConfigID *config) {
   1388     VAStatus vaStatus;
   1389     VAConfigAttrib attrib;
   1390     attrib.type = VAConfigAttribRTFormat;
   1391     attrib.value = VA_RT_FORMAT_YUV420;
   1392 
   1393     if (config == NULL) {
   1394         ETRACE("Invalid parameter!");
   1395         return DECODE_FAIL;
   1396     }
   1397 
   1398     vaStatus = vaCreateConfig(
   1399             mVADisplay,
   1400             profile,
   1401             VAEntrypointVLD,
   1402             &attrib,
   1403             1,
   1404             config);
   1405 
   1406     CHECK_VA_STATUS("vaCreateConfig");
   1407 
   1408     return DECODE_SUCCESS;
   1409 }
   1410 #endif
   1411 Decode_Status VideoDecoderBase::checkHardwareCapability() {
   1412     return DECODE_SUCCESS;
   1413 }
   1414 
   1415 void VideoDecoderBase::drainDecodingErrors(VideoErrorBuffer *outErrBuf, VideoRenderBuffer *currentSurface) {
   1416     if (mErrReportEnabled && outErrBuf && currentSurface) {
   1417         memcpy(outErrBuf, &(currentSurface->errBuf), sizeof(VideoErrorBuffer));
   1418 
   1419         currentSurface->errBuf.errorNumber = 0;
   1420         currentSurface->errBuf.timeStamp = INVALID_PTS;
   1421     }
   1422     if (outErrBuf)
   1423         VTRACE("%s: error number is %d", __FUNCTION__, outErrBuf->errorNumber);
   1424 }
   1425 
   1426 void VideoDecoderBase::fillDecodingErrors(VideoRenderBuffer *currentSurface) {
   1427     VAStatus ret;
   1428 
   1429     if (mErrReportEnabled) {
   1430         currentSurface->errBuf.timeStamp = currentSurface->timeStamp;
   1431         // TODO: is 10 a suitable number?
   1432         VASurfaceDecodeMBErrors *err_drv_output = NULL;
   1433         ret = vaQuerySurfaceError(mVADisplay, currentSurface->surface, VA_STATUS_ERROR_DECODING_ERROR, (void **)&err_drv_output);
   1434         if (ret || !err_drv_output) {
   1435             WTRACE("vaQuerySurfaceError failed.");
   1436             return;
   1437         }
   1438 
   1439         int offset =  0x1 & currentSurface->errBuf.errorNumber;// offset is either 0 or 1
   1440         for (int i = 0; i < MAX_ERR_NUM - offset; i++) {
   1441             if (err_drv_output[i].status != -1) {
   1442                 currentSurface->errBuf.errorNumber++;
   1443                 currentSurface->errBuf.errorArray[i + offset].type = DecodeMBError;
   1444                 currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.start_mb = err_drv_output[i].start_mb;
   1445                 currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.end_mb = err_drv_output[i].end_mb;
   1446                 currentSurface->errBuf.errorArray[i + offset].num_mbs = err_drv_output[i].end_mb - err_drv_output[i].start_mb + 1;
   1447                 ITRACE("Error Index[%d]: type = %d, start_mb = %d, end_mb = %d",
   1448                     currentSurface->errBuf.errorNumber - 1,
   1449                     currentSurface->errBuf.errorArray[i + offset].type,
   1450                     currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.start_mb,
   1451                     currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.end_mb);
   1452             } else break;
   1453         }
   1454         ITRACE("%s: error number of current surface is %d, timestamp @%llu",
   1455             __FUNCTION__, currentSurface->errBuf.errorNumber, currentSurface->timeStamp);
   1456     }
   1457 }
   1458 
   1459 void VideoDecoderBase::setRotationDegrees(int32_t rotationDegrees) {
   1460     if (mRotationDegrees == rotationDegrees) {
   1461         return;
   1462     }
   1463 
   1464     ITRACE("set new rotation degree: %d", rotationDegrees);
   1465     VADisplayAttribute rotate;
   1466     rotate.type = VADisplayAttribRotation;
   1467     rotate.value = VA_ROTATION_NONE;
   1468     if (rotationDegrees == 0)
   1469         rotate.value = VA_ROTATION_NONE;
   1470     else if (rotationDegrees == 90)
   1471         rotate.value = VA_ROTATION_90;
   1472     else if (rotationDegrees == 180)
   1473         rotate.value = VA_ROTATION_180;
   1474     else if (rotationDegrees == 270)
   1475         rotate.value = VA_ROTATION_270;
   1476 
   1477     VAStatus ret = vaSetDisplayAttributes(mVADisplay, &rotate, 1);
   1478     if (ret) {
   1479         ETRACE("Failed to set rotation degree.");
   1480     }
   1481     mRotationDegrees = rotationDegrees;
   1482 }
   1483 
   1484 void VideoDecoderBase::setRenderRect() {
   1485 
   1486     if (!mVADisplay)
   1487         return;
   1488 
   1489     VAStatus ret;
   1490     VARectangle rect;
   1491     rect.x = mVideoFormatInfo.cropLeft;
   1492     rect.y = mVideoFormatInfo.cropTop;
   1493     rect.width = mVideoFormatInfo.width - (mVideoFormatInfo.cropLeft + mVideoFormatInfo.cropRight);
   1494     rect.height = mVideoFormatInfo.height - (mVideoFormatInfo.cropBottom + mVideoFormatInfo.cropTop);
   1495 
   1496     VADisplayAttribute render_rect;
   1497     render_rect.type = VADisplayAttribRenderRect;
   1498     render_rect.value = (long)&rect;
   1499 
   1500     ret = vaSetDisplayAttributes(mVADisplay, &render_rect, 1);
   1501     if (ret) {
   1502         ETRACE("Failed to set rotation degree.");
   1503     }
   1504 }
   1505