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