Home | History | Annotate | Download | only in base
      1 /*
      2  * Copyright (C) 2012 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 
     18 #include <math.h>
     19 #include <utils/Errors.h>
     20 #include "isv_processor.h"
     21 #include "isv_profile.h"
     22 #include "isv_omxcomponent.h"
     23 
     24 //#define LOG_NDEBUG 0
     25 #undef LOG_TAG
     26 #define LOG_TAG "isv-omxil"
     27 
     28 using namespace android;
     29 
     30 #define MAX_RETRY_NUM   10
     31 
     32 ISVProcessor::ISVProcessor(bool canCallJava,
     33         sp<ISVBufferManager> bufferManager,
     34         sp<ISVProcessorObserver> owner,
     35         uint32_t width, uint32_t height)
     36     :Thread(canCallJava),
     37     mpOwner(owner),
     38     mThreadId(NULL),
     39     mThreadRunning(false),
     40     mISVWorker(NULL),
     41     mBufferManager(bufferManager),
     42     mOutputProcIdx(0),
     43     mInputProcIdx(0),
     44     mNumTaskInProcesing(0),
     45     mNumRetry(0),
     46     mError(false),
     47     mbFlush(false),
     48     mbBypass(false),
     49     mFlagEnd(false),
     50     mFilters(0)
     51 {
     52     //FIXME: for 1920 x 1088, we also consider it as 1080p
     53     mISVProfile = new ISVProfile(width, (height == 1088) ? 1080 : height);
     54 
     55     // get platform ISV cap first
     56     mFilters = mISVProfile->getFilterStatus();
     57 
     58     // turn off filters if dynamic vpp/frc setting is off
     59     if (!ISVProfile::isVPPOn())
     60         mFilters &= FilterFrameRateConversion;
     61 
     62     if (!ISVProfile::isFRCOn())
     63         mFilters &= ~FilterFrameRateConversion;
     64 
     65     //FIXME: move this into profile.
     66     if (width > 2048)
     67         mFilters &= ~FilterSharpening;
     68 
     69     memset(&mFilterParam, 0, sizeof(mFilterParam));
     70     //FIXME: we don't support scaling yet, so set src region equal to dst region
     71     mFilterParam.srcWidth = mFilterParam.dstWidth = width;
     72     mFilterParam.srcHeight = mFilterParam.dstHeight = height;
     73     mOutputBuffers.clear();
     74     mInputBuffers.clear();
     75     mTimeWindow.clear();
     76 }
     77 
     78 ISVProcessor::~ISVProcessor() {
     79     ALOGV("ISVProcessor is deleted");
     80     flush();
     81     mOutputBuffers.clear();
     82     mInputBuffers.clear();
     83 
     84     mISVProfile = NULL;
     85     mFilters = 0;
     86     memset(&mFilterParam, 0, sizeof(mFilterParam));
     87 }
     88 
     89 status_t ISVProcessor::readyToRun()
     90 {
     91     mThreadId = androidGetThreadId();
     92     //do init ops here
     93     return Thread::readyToRun();
     94 }
     95 
     96 void ISVProcessor::start()
     97 {
     98     ALOGD_IF(ISV_THREAD_DEBUG, "ISVProcessor::start");
     99 
    100     if (mISVWorker == NULL) {
    101         mISVWorker = new ISVWorker();
    102         if (STATUS_OK != mISVWorker->init(mFilterParam.srcWidth, mFilterParam.srcHeight))
    103             ALOGE("%s: mISVWorker init failed", __func__);
    104     }
    105 
    106     mBufferManager->setWorker(mISVWorker);
    107 
    108     this->run("ISVProcessor", ANDROID_PRIORITY_NORMAL);
    109     mThreadRunning = true;
    110     return;
    111 }
    112 
    113 void ISVProcessor::stop()
    114 {
    115     ALOGD_IF(ISV_THREAD_DEBUG, "ISVProcessor::stop");
    116 
    117     if(mThreadRunning) {
    118         this->requestExit();
    119         {
    120             Mutex::Autolock autoLock(mLock);
    121             mRunCond.signal();
    122         }
    123         this->requestExitAndWait();
    124         mThreadRunning = false;
    125     }
    126 
    127     if (STATUS_OK != mISVWorker->deinit())
    128         ALOGE("%s: mISVWorker deinit failed", __func__);
    129 
    130     mISVWorker = NULL;
    131     return;
    132 }
    133 
    134 bool ISVProcessor::getBufForFirmwareOutput(Vector<ISVBuffer*> *fillBufList,uint32_t *fillBufNum){
    135     uint32_t i = 0;
    136     // output buffer number for filling
    137     *fillBufNum = 0;
    138     uint32_t needFillNum = 0;
    139     OMX_BUFFERHEADERTYPE *outputBuffer;
    140 
    141     //output data available
    142     needFillNum = mISVWorker->getFillBufCount();
    143     if (mOutputProcIdx < needFillNum ||
    144             mInputProcIdx < 1) {
    145         ALOGE("%s: no enough input or output buffer which need to be sync", __func__);
    146         return false;
    147     }
    148 
    149     if ((needFillNum == 0) || (needFillNum > 4))
    150        return false;
    151 
    152     Mutex::Autolock autoLock(mOutputLock);
    153     for (i = 0; i < needFillNum; i++) {
    154         //fetch the render buffer from the top of output buffer queue
    155         outputBuffer = mOutputBuffers.itemAt(i);
    156         if (!outputBuffer) {
    157             ALOGE("%s: failed to fetch output buffer for sync.", __func__);
    158             return false;
    159         }
    160         unsigned long fillHandle = reinterpret_cast<unsigned long>(outputBuffer->pBuffer);
    161         ISVBuffer* fillBuf = mBufferManager->mapBuffer(fillHandle);
    162         fillBufList->push_back(fillBuf);
    163     }
    164 
    165     *fillBufNum  = i;
    166     return true;
    167 }
    168 
    169 
    170 status_t ISVProcessor::updateFirmwareOutputBufStatus(uint32_t fillBufNum) {
    171     int64_t timeUs;
    172     OMX_BUFFERHEADERTYPE *outputBuffer;
    173     OMX_BUFFERHEADERTYPE *inputBuffer;
    174     OMX_ERRORTYPE err;
    175     bool cropChanged = false;
    176 
    177     if (mInputBuffers.empty()) {
    178         ALOGE("%s: input buffer queue is empty. no buffer need to be sync", __func__);
    179         return UNKNOWN_ERROR;
    180     }
    181 
    182     if (mOutputBuffers.size() < fillBufNum) {
    183         ALOGE("%s: no enough output buffer which need to be sync", __func__);
    184         return UNKNOWN_ERROR;
    185     }
    186     // remove one buffer from intput buffer queue
    187     {
    188         Mutex::Autolock autoLock(mInputLock);
    189         inputBuffer = mInputBuffers.itemAt(0);
    190         unsigned long inputHandle = reinterpret_cast<unsigned long>(inputBuffer->pBuffer);
    191         ISVBuffer* inputBuf = mBufferManager->mapBuffer(inputHandle);
    192         uint32_t flags = inputBuf->getFlags();
    193 
    194         if (flags & ISVBuffer::ISV_BUFFER_CROP_CHANGED) {
    195             err = mpOwner->reportOutputCrop();
    196             if (err != OMX_ErrorNone) {
    197                 ALOGE("%s: failed to reportOutputCrop", __func__);
    198                 return UNKNOWN_ERROR;
    199             }
    200             cropChanged = true;
    201             inputBuf->unsetFlag(ISVBuffer::ISV_BUFFER_CROP_CHANGED);
    202         }
    203 
    204         err = mpOwner->releaseBuffer(kPortIndexInput, inputBuffer, false);
    205         if (err != OMX_ErrorNone) {
    206             ALOGE("%s: failed to fillInputBuffer", __func__);
    207             return UNKNOWN_ERROR;
    208         }
    209 
    210         mInputBuffers.removeAt(0);
    211         ALOGD_IF(ISV_THREAD_DEBUG, "%s: fetch buffer %u from input buffer queue for fill to decoder, and then queue size is %d", __func__,
    212                 inputBuffer, mInputBuffers.size());
    213         mInputProcIdx--;
    214     }
    215 
    216     //set the time stamp for interpreted frames
    217     {
    218         Mutex::Autolock autoLock(mOutputLock);
    219         timeUs = mOutputBuffers[0]->nTimeStamp;
    220 
    221         for(uint32_t i = 0; i < fillBufNum; i++) {
    222             outputBuffer = mOutputBuffers.itemAt(i);
    223             if (fillBufNum > 1) {
    224                 if (mFilterParam.frameRate == 24) {
    225                     if (fillBufNum == 2) {
    226                         outputBuffer->nTimeStamp = timeUs + 1000000ll * (i + 1) / 60 - 1000000ll * 1 / 24;
    227                     } else if (fillBufNum == 3) {
    228                         outputBuffer->nTimeStamp = timeUs + 1000000ll * (i + 3) / 60 - 1000000ll * 2 / 24;
    229                     }
    230                 }
    231                 else
    232                     outputBuffer->nTimeStamp = timeUs - 1000000ll * (fillBufNum - i - 1) / (mFilterParam.frameRate * 2);
    233             }
    234 
    235             //return filled buffers for rendering
    236             //skip rendering for crop change
    237             err = mpOwner->releaseBuffer(kPortIndexOutput, outputBuffer, cropChanged);
    238 
    239             if (err != OMX_ErrorNone) {
    240                 ALOGE("%s: failed to releaseOutputBuffer", __func__);
    241                 return UNKNOWN_ERROR;
    242             }
    243 
    244             ALOGD_IF(ISV_THREAD_DEBUG, "%s: fetch buffer %u(timestamp %.2f ms) from output buffer queue for render, and then queue size is %d", __func__,
    245                     outputBuffer, outputBuffer->nTimeStamp/1E3, mOutputBuffers.size());
    246         }
    247         // remove filled buffers from output buffer queue
    248         mOutputBuffers.removeItemsAt(0, fillBufNum);
    249         mOutputProcIdx -= fillBufNum;
    250     }
    251     return OK;
    252 }
    253 
    254 
    255 bool ISVProcessor::getBufForFirmwareInput(Vector<ISVBuffer*> *procBufList,
    256                                    ISVBuffer **inputBuf,
    257                                    uint32_t *procBufNum)
    258 {
    259     OMX_BUFFERHEADERTYPE *outputBuffer;
    260     OMX_BUFFERHEADERTYPE *inputBuffer;
    261 
    262     if (mbFlush) {
    263         *inputBuf = NULL;
    264         *procBufNum = 0;
    265         return true;
    266     }
    267 
    268     int32_t procBufCount = mISVWorker->getProcBufCount();
    269     if ((procBufCount == 0) || (procBufCount > 4)) {
    270        return false;
    271     }
    272 
    273     //fetch a input buffer for processing
    274     {
    275         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqiring mInputLock", __func__);
    276         Mutex::Autolock autoLock(mInputLock);
    277         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqired mInputLock", __func__);
    278         inputBuffer = mInputBuffers.itemAt(mInputProcIdx);
    279         if (!inputBuffer) {
    280             ALOGE("%s: failed to get input buffer for processing.", __func__);
    281             return false;
    282         }
    283         unsigned long inputHandle = reinterpret_cast<unsigned long>(inputBuffer->pBuffer);
    284         *inputBuf = mBufferManager->mapBuffer(inputHandle);
    285         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: releasing mInputLock", __func__);
    286     }
    287 
    288     //fetch output buffers for processing
    289     {
    290         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqiring mOutputLock", __func__);
    291         Mutex::Autolock autoLock(mOutputLock);
    292         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqired mOutputLock", __func__);
    293         for (int32_t i = 0; i < procBufCount; i++) {
    294             outputBuffer = mOutputBuffers.itemAt(mOutputProcIdx + i);
    295             if (!outputBuffer) {
    296                 ALOGE("%s: failed to get output buffer for processing.", __func__);
    297                 return false;
    298             }
    299             unsigned long outputHandle = reinterpret_cast<unsigned long>(outputBuffer->pBuffer);
    300             procBufList->push_back(mBufferManager->mapBuffer(outputHandle));
    301         }
    302         *procBufNum = procBufCount;
    303         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: releasing mOutputLock", __func__);
    304     }
    305 
    306     return true;
    307 }
    308 
    309 
    310 status_t ISVProcessor::updateFirmwareInputBufStatus(uint32_t procBufNum)
    311 {
    312     OMX_BUFFERHEADERTYPE *outputBuffer;
    313     OMX_BUFFERHEADERTYPE *inputBuffer;
    314 
    315     inputBuffer = mInputBuffers.itemAt(mInputProcIdx);
    316     mInputProcIdx++;
    317 
    318     Mutex::Autolock autoLock(mOutputLock);
    319     for(uint32_t i = 0; i < procBufNum; i++) {
    320         outputBuffer = mOutputBuffers.editItemAt(mOutputProcIdx + i);
    321         // set output buffer timestamp as the same as input
    322         outputBuffer->nTimeStamp = inputBuffer->nTimeStamp;
    323         outputBuffer->nFilledLen = inputBuffer->nFilledLen;
    324         outputBuffer->nOffset = inputBuffer->nOffset;
    325         outputBuffer->nFlags = inputBuffer->nFlags;
    326         //outputBuffer->nTickCount = inputBuffer->nTickCount;
    327         //outputBuffer->pMarkData = intputBuffer->pMarkData;
    328     }
    329     mOutputProcIdx += procBufNum;
    330     return OK;
    331 }
    332 
    333 
    334 bool ISVProcessor::isReadytoRun()
    335 {
    336     ALOGD_IF(ISV_THREAD_DEBUG, "%s: mISVWorker->getProcBufCount() return %d", __func__,
    337             mISVWorker->getProcBufCount());
    338     if (mInputProcIdx < mInputBuffers.size()
    339             && (mOutputBuffers.size() - mOutputProcIdx) >= mISVWorker->getProcBufCount())
    340        return true;
    341     else
    342        return false;
    343 }
    344 
    345 
    346 bool ISVProcessor::threadLoop() {
    347     uint32_t procBufNum = 0, fillBufNum = 0;
    348     ISVBuffer* inputBuf;
    349     Vector<ISVBuffer*> procBufList;
    350     Vector<ISVBuffer*> fillBufList;
    351     uint32_t flags = 0;
    352     bool bGetBufSuccess = true;
    353 
    354     Mutex::Autolock autoLock(mLock);
    355 
    356     if (!isReadytoRun() && !mbFlush) {
    357         mRunCond.wait(mLock);
    358     }
    359 
    360     if (isReadytoRun() || mbFlush) {
    361         procBufList.clear();
    362         bool bGetInBuf = getBufForFirmwareInput(&procBufList, &inputBuf, &procBufNum);
    363         if (bGetInBuf) {
    364             if (!mbFlush)
    365                 flags = mInputBuffers[mInputProcIdx]->nFlags;
    366             status_t ret = mISVWorker->process(inputBuf, procBufList, procBufNum, mbFlush, flags);
    367             if (ret == STATUS_OK) {
    368                 // for seek and EOS
    369                 if (mbFlush) {
    370                     mISVWorker->reset();
    371                     flush();
    372 
    373                     mNumTaskInProcesing = 0;
    374                     mInputProcIdx = 0;
    375                     mOutputProcIdx = 0;
    376 
    377                     mbFlush = false;
    378 
    379                     Mutex::Autolock endLock(mEndLock);
    380                     mEndCond.signal();
    381                     return true;
    382                 }
    383                 mNumTaskInProcesing++;
    384                 updateFirmwareInputBufStatus(procBufNum);
    385             } else {
    386                 mbBypass = true;
    387                 flush();
    388                 ALOGE("VSP process error %d .... ISV changes to bypass mode", __LINE__);
    389             }
    390         }
    391     }
    392 
    393     ALOGV("mNumTaskInProcesing %d", mNumTaskInProcesing);
    394     while ((mNumTaskInProcesing > 0) && mNumTaskInProcesing >= mISVWorker->mNumForwardReferences && bGetBufSuccess ) {
    395         fillBufList.clear();
    396         bGetBufSuccess = getBufForFirmwareOutput(&fillBufList, &fillBufNum);
    397         ALOGD_IF(ISV_THREAD_DEBUG, "%s: bGetOutput %d, buf num %d", __func__,
    398                 bGetBufSuccess, fillBufNum);
    399         if (bGetBufSuccess) {
    400             status_t ret = mISVWorker->fill(fillBufList, fillBufNum);
    401             if (ret == STATUS_OK) {
    402                 mNumTaskInProcesing--;
    403                 ALOGV("mNumTaskInProcesing: %d ...", mNumTaskInProcesing);
    404                 updateFirmwareOutputBufStatus(fillBufNum);
    405             } else {
    406                 mError = true;
    407                 ALOGE("ISV read firmware data error! Thread EXIT...");
    408                 return false;
    409             }
    410         }
    411     }
    412 
    413     return true;
    414 }
    415 
    416 bool ISVProcessor::isCurrentThread() const {
    417     return mThreadId == androidGetThreadId();
    418 }
    419 
    420 inline bool ISVProcessor::isFrameRateValid(uint32_t fps)
    421 {
    422     return (fps == 15 || fps == 24 || fps == 25 || fps == 30 || fps == 50 || fps == 60) ? true : false;
    423 }
    424 
    425 status_t ISVProcessor::configFRC(uint32_t fps)
    426 {
    427     if (isFrameRateValid(fps)) {
    428         if (fps == 50 || fps == 60) {
    429             ALOGD_IF(ISV_THREAD_DEBUG, "%s: %d fps don't need do FRC, so disable FRC", __func__, fps);
    430             mFilters &= ~FilterFrameRateConversion;
    431             mFilterParam.frcRate = FRC_RATE_1X;
    432         } else {
    433             mFilterParam.frameRate = fps;
    434             mFilterParam.frcRate = mISVProfile->getFRCRate(mFilterParam.frameRate);
    435             ALOGD_IF(ISV_THREAD_DEBUG, "%s: fps is set to %d, frc rate is %d", __func__,
    436                     mFilterParam.frameRate, mFilterParam.frcRate);
    437         }
    438         return OK;
    439     }
    440 
    441     return UNKNOWN_ERROR;
    442 }
    443 
    444 status_t ISVProcessor::calculateFps(int64_t timeStamp, uint32_t* fps)
    445 {
    446     int32_t i = 0;
    447     *fps = 0;
    448 
    449     mTimeWindow.push_back(timeStamp);
    450     if (mTimeWindow.size() > WINDOW_SIZE) {
    451         mTimeWindow.removeAt(0);
    452     }
    453     else if (mTimeWindow.size() < WINDOW_SIZE)
    454         return NOT_ENOUGH_DATA;
    455 
    456     int64_t delta = mTimeWindow[WINDOW_SIZE-1] - mTimeWindow[0];
    457     if (delta == 0)
    458         return NOT_ENOUGH_DATA;
    459 
    460     *fps = ceil(1.0 / delta * 1E6 * (WINDOW_SIZE-1));
    461     return OK;
    462 }
    463 
    464 status_t ISVProcessor::configFilters(OMX_BUFFERHEADERTYPE* buffer)
    465 {
    466     if ((mFilters & FilterFrameRateConversion) != 0) {
    467         if (!isFrameRateValid(mFilterParam.frameRate)) {
    468             if (mNumRetry++ < MAX_RETRY_NUM) {
    469                 uint32_t fps = 0;
    470                 if (OK != calculateFps(buffer->nTimeStamp, &fps))
    471                     return NOT_ENOUGH_DATA;
    472 
    473                 if (OK != configFRC(fps))
    474                     return NOT_ENOUGH_DATA;
    475             } else {
    476                 ALOGD_IF(ISV_THREAD_DEBUG, "%s: exceed max retry to get a valid frame rate(%d), disable FRC", __func__,
    477                         mFilterParam.frameRate);
    478                 mFilters &= ~FilterFrameRateConversion;
    479                 mFilterParam.frcRate = FRC_RATE_1X;
    480             }
    481         }
    482     }
    483 
    484     if ((buffer->nFlags & OMX_BUFFERFLAG_TFF) != 0 ||
    485             (buffer->nFlags & OMX_BUFFERFLAG_BFF) != 0)
    486         mFilters |= FilterDeinterlacing;
    487     else
    488         mFilters &= ~FilterDeinterlacing;
    489 
    490     if (mFilters == 0) {
    491         ALOGI("%s: no filter need to be config, bypass ISV", __func__);
    492         return UNKNOWN_ERROR;
    493     }
    494 
    495     //config filters to mISVWorker
    496     return (mISVWorker->configFilters(mFilters, &mFilterParam) == STATUS_OK) ? OK : UNKNOWN_ERROR;
    497 }
    498 
    499 void ISVProcessor::addInput(OMX_BUFFERHEADERTYPE* input)
    500 {
    501     if (mbFlush) {
    502         mpOwner->releaseBuffer(kPortIndexInput, input, true);
    503         return;
    504     }
    505 
    506     if (mbBypass) {
    507         // return this buffer to framework
    508         mpOwner->releaseBuffer(kPortIndexOutput, input, false);
    509         return;
    510     }
    511 
    512     if (input->nFlags & OMX_BUFFERFLAG_EOS) {
    513         mpOwner->releaseBuffer(kPortIndexInput, input, true);
    514         notifyFlush();
    515         return;
    516     }
    517 
    518     status_t ret = configFilters(input);
    519     if (ret == NOT_ENOUGH_DATA) {
    520         // release this buffer if frc is not ready.
    521         mpOwner->releaseBuffer(kPortIndexInput, input, false);
    522         ALOGD_IF(ISV_THREAD_DEBUG, "%s: frc rate is not ready, release this buffer %u, fps %d", __func__,
    523                 input, mFilterParam.frameRate);
    524         return;
    525     } else if (ret == UNKNOWN_ERROR) {
    526         ALOGD_IF(ISV_THREAD_DEBUG, "%s: configFilters failed, bypass ISV", __func__);
    527         mbBypass = true;
    528         mpOwner->releaseBuffer(kPortIndexOutput, input, false);
    529         return;
    530     }
    531 
    532     {
    533         //put the decoded buffer into fill buffer queue
    534         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqiring mInputLock", __func__);
    535         Mutex::Autolock autoLock(mInputLock);
    536         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqired mInputLock", __func__);
    537 
    538         mInputBuffers.push_back(input);
    539         ALOGD_IF(ISV_THREAD_DEBUG, "%s: hold pBuffer %u in input buffer queue. Intput queue size is %d, mInputProIdx %d.\
    540                 Output queue size is %d, mOutputProcIdx %d", __func__,
    541                 input, mInputBuffers.size(), mInputProcIdx,
    542                 mOutputBuffers.size(), mOutputProcIdx);
    543         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: releasing mInputLock", __func__);
    544     }
    545 
    546     {
    547         Mutex::Autolock autoLock(mLock);
    548         mRunCond.signal();
    549     }
    550     return;
    551 }
    552 
    553 void ISVProcessor::addOutput(OMX_BUFFERHEADERTYPE* output)
    554 {
    555     if (mbFlush) {
    556         mpOwner->releaseBuffer(kPortIndexOutput, output, true);
    557         return;
    558     }
    559 
    560     if (mbBypass || mOutputBuffers.size() >= MIN_OUTPUT_NUM) {
    561         // return this buffer to decoder
    562         mpOwner->releaseBuffer(kPortIndexInput, output, false);
    563         return;
    564     }
    565 
    566     {
    567         //push the buffer into the output queue if it is not full
    568         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqiring mOutputLock", __func__);
    569         Mutex::Autolock autoLock(mOutputLock);
    570         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqired mOutputLock", __func__);
    571 
    572         mOutputBuffers.push_back(output);
    573         ALOGD_IF(ISV_THREAD_DEBUG, "%s: hold pBuffer %u in output buffer queue. Input queue size is %d, mInputProIdx %d.\
    574                 Output queue size is %d, mOutputProcIdx %d", __func__,
    575                 output, mInputBuffers.size(), mInputProcIdx,
    576                 mOutputBuffers.size(), mOutputProcIdx);
    577         ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: releasing mOutputLock", __func__);
    578     }
    579 
    580     {
    581         Mutex::Autolock autoLock(mLock);
    582         mRunCond.signal();
    583     }
    584     return;
    585 }
    586 
    587 void ISVProcessor::notifyFlush()
    588 {
    589     if (mInputBuffers.empty() && mOutputBuffers.empty()) {
    590         ALOGD_IF(ISV_THREAD_DEBUG, "%s: input and ouput buffer queue is empty, nothing need to do", __func__);
    591         return;
    592     }
    593 
    594     Mutex::Autolock autoLock(mLock);
    595     mbFlush = true;
    596     mRunCond.signal();
    597     ALOGD_IF(ISV_THREAD_DEBUG, "wake up proc thread");
    598     return;
    599 }
    600 
    601 void ISVProcessor::waitFlushFinished()
    602 {
    603     Mutex::Autolock endLock(mEndLock);
    604     ALOGD_IF(ISV_THREAD_DEBUG, "waiting mEnd lock(seek finish) ");
    605     while(mbFlush) {
    606         mEndCond.wait(mEndLock);
    607     }
    608     return;
    609 }
    610 
    611 void ISVProcessor::flush()
    612 {
    613     OMX_BUFFERHEADERTYPE* pBuffer = NULL;
    614     {
    615         Mutex::Autolock autoLock(mInputLock);
    616         while (!mInputBuffers.empty()) {
    617             pBuffer = mInputBuffers.itemAt(0);
    618             mpOwner->releaseBuffer(kPortIndexInput, pBuffer, true);
    619             ALOGD_IF(ISV_THREAD_DEBUG, "%s: Flush the pBuffer %u in input buffer queue.", __func__, pBuffer);
    620             mInputBuffers.removeAt(0);
    621         }
    622     }
    623     {
    624         Mutex::Autolock autoLock(mOutputLock);
    625         while (!mOutputBuffers.empty()) {
    626             pBuffer = mOutputBuffers.itemAt(0);
    627             mpOwner->releaseBuffer(kPortIndexOutput, pBuffer, true);
    628             ALOGD_IF(ISV_THREAD_DEBUG, "%s: Flush the pBuffer %u in output buffer queue.", __func__, pBuffer);
    629             mOutputBuffers.removeAt(0);
    630         }
    631     }
    632     //flush finished.
    633     return;
    634 }
    635