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
28using namespace android;
29
30#define MAX_RETRY_NUM   10
31
32ISVProcessor::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
78ISVProcessor::~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
89status_t ISVProcessor::readyToRun()
90{
91    mThreadId = androidGetThreadId();
92    //do init ops here
93    return Thread::readyToRun();
94}
95
96void 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
113void 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
134bool 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
170status_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
255bool 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
310status_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
334bool 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
346bool 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
416bool ISVProcessor::isCurrentThread() const {
417    return mThreadId == androidGetThreadId();
418}
419
420inline 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
425status_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
444status_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
464status_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
499void 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
553void 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
587void 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
601void 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
611void 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