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 
20 #include <OMX_Component.h>
21 #include "isv_omxcomponent.h"
22 #include <media/hardware/HardwareAPI.h>
23 #include "isv_profile.h"
24 #include <OMX_IndexExt.h>
25 #include <hal_public.h>
26 
27 #include "OMX_adaptor.h"
28 
29 //#define LOG_NDEBUG 0
30 #undef LOG_TAG
31 #define LOG_TAG "isv-omxil"
32 
33 #define OUTPUT_STARTUP_DEC_BUF_NUM (38)
34 #define FLUSH_WIDTH  352
35 #define FLUSH_HEIGHT 288
36 
37 using namespace android;
38 
39 /**********************************************************************************
40  * component methods & helpers
41  */
42 #define GET_ISVOMX_COMPONENT(hComponent)                                    \
43     ISVComponent *pComp = static_cast<ISVComponent*>                        \
44         ((static_cast<OMX_COMPONENTTYPE*>(hComponent))->pComponentPrivate); \
45     if (!pComp)                                                             \
46         return OMX_ErrorBadParameter;
47 
48 Vector<ISVComponent*> ISVComponent::g_isv_components;
49 
50 extern MRM_OMX_Adaptor* g_mrm_omx_adaptor;
51 
52 #ifndef TARGET_VPP_USE_GEN
53 //global, static
54 sp<ISVProcessor> ISVComponent::mProcThread = NULL;
55 #endif
56 
57 //global, static
58 pthread_mutex_t ISVComponent::ProcThreadInstanceLock = PTHREAD_MUTEX_INITIALIZER;
59 
ISVComponent(OMX_PTR pAppData)60 ISVComponent::ISVComponent(
61         OMX_PTR pAppData)
62     :   mComponent(NULL),
63         mpCallBacks(NULL),
64         mCore(NULL),
65         mpISVCallBacks(NULL),
66         mISVBufferManager(NULL),
67         mThreadRunning(false),
68         mProcThreadObserver(NULL),
69         mNumISVBuffers(MIN_ISV_BUFFER_NUM),
70         mNumDecoderBuffers(0),
71         mNumDecoderBuffersBak(0),
72         mOutputDecoderBufferNum(0),
73         mWidth(0),
74         mHeight(0),
75         mUseAndroidNativeBufferIndex(0),
76         mStoreMetaDataInBuffersIndex(0),
77         mHackFormat(0),
78         mUseAndroidNativeBuffer(false),
79         mUseAndroidNativeBuffer2(false),
80         mVPPEnabled(false),
81         mVPPFlushing(false),
82         mOutputCropChanged(false),
83         mInitialized(false),
84 #ifdef TARGET_VPP_USE_GEN
85         mProcThread(NULL),
86 #endif
87         mOwnProcessor(false)
88 {
89     memset(&mBaseComponent, 0, sizeof(OMX_COMPONENTTYPE));
90     /* handle initialization */
91     SetTypeHeader(&mBaseComponent, sizeof(mBaseComponent));
92     mBaseComponent.pApplicationPrivate = pAppData;
93     mBaseComponent.pComponentPrivate = static_cast<OMX_PTR>(this);
94 
95     /* connect handle's functions */
96     mBaseComponent.GetComponentVersion = NULL;
97     mBaseComponent.SendCommand = SendCommand;
98     mBaseComponent.GetParameter = GetParameter;
99     mBaseComponent.SetParameter = SetParameter;
100     mBaseComponent.GetConfig = GetConfig;
101     mBaseComponent.SetConfig = SetConfig;
102     mBaseComponent.GetExtensionIndex = GetExtensionIndex;
103     mBaseComponent.GetState = GetState;
104     mBaseComponent.ComponentTunnelRequest = NULL;
105     mBaseComponent.UseBuffer = UseBuffer;
106     mBaseComponent.AllocateBuffer = AllocateBuffer;
107     mBaseComponent.FreeBuffer = FreeBuffer;
108     mBaseComponent.EmptyThisBuffer = EmptyThisBuffer;
109     mBaseComponent.FillThisBuffer = FillThisBuffer;
110     mBaseComponent.SetCallbacks = SetCallbacks;
111     mBaseComponent.ComponentDeInit = NULL;
112     mBaseComponent.UseEGLImage = NULL;
113     mBaseComponent.ComponentRoleEnum = ComponentRoleEnum;
114     g_isv_components.push_back(static_cast<ISVComponent*>(this));
115 
116     mVPPOn = ISVProfile::isFRCOn() || ISVProfile::isVPPOn();
117     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPPOn %d", __func__, mVPPOn);
118 
119     if (mISVBufferManager == NULL) {
120         mISVBufferManager = new ISVBufferManager();
121     }
122 
123 }
124 
~ISVComponent()125 ISVComponent::~ISVComponent()
126 {
127     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
128     if (mpISVCallBacks) {
129         free(mpISVCallBacks);
130         mpISVCallBacks = NULL;
131     }
132 
133     for (OMX_U32 i = 0; i < g_isv_components.size(); i++) {
134         if (g_isv_components.itemAt(i) == static_cast<ISVComponent*>(this)) {
135             g_isv_components.removeAt(i);
136         }
137     }
138 
139     memset(&mBaseComponent, 0, sizeof(OMX_COMPONENTTYPE));
140     deinit();
141     mVPPOn = false;
142     mISVBufferManager = NULL;
143 }
144 
init(int32_t width,int32_t height)145 status_t ISVComponent::init(int32_t width, int32_t height)
146 {
147     if (mInitialized)
148         return STATUS_OK;
149 
150     bool frcOn = false;
151     if (mProcThreadObserver == NULL)
152         mProcThreadObserver = new ISVProcThreadObserver(&mBaseComponent, mComponent, mpCallBacks, mISVBufferManager);
153 
154     pthread_mutex_lock(&ProcThreadInstanceLock);
155     if (mProcThread == NULL) {
156         mProcThread = new ISVProcessor(false, mISVBufferManager, mProcThreadObserver, width, height);
157         mOwnProcessor = true;
158         mProcThread->start();
159     }
160 #ifndef TARGET_VPP_USE_GEN
161     else {
162         mVPPEnabled = false;
163         mOwnProcessor = false;
164         ALOGI("%s: failed to alloc isv processor", __func__);
165         pthread_mutex_unlock(&ProcThreadInstanceLock);
166         return STATUS_ERROR;
167     }
168 #endif
169     pthread_mutex_unlock(&ProcThreadInstanceLock);
170 
171     mInitialized = true;
172     return STATUS_OK;
173 }
174 
deinit()175 void ISVComponent::deinit()
176 {
177     pthread_mutex_lock(&ProcThreadInstanceLock);
178     if (mOwnProcessor) {
179         if (mProcThread != NULL) {
180             mProcThread->stop();
181             mProcThread = NULL;
182             ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: delete ISV processor ", __func__);
183         }
184     }
185     pthread_mutex_unlock(&ProcThreadInstanceLock);
186 
187     mProcThreadObserver = NULL;
188 
189     mInitialized = false;
190 }
191 
getCallBacks(OMX_CALLBACKTYPE * pCallBacks)192 OMX_CALLBACKTYPE* ISVComponent::getCallBacks(OMX_CALLBACKTYPE* pCallBacks)
193 {
194     //reset component callback functions
195     mpCallBacks = pCallBacks;
196     if (mpISVCallBacks) {
197         free(mpISVCallBacks);
198         mpISVCallBacks = NULL;
199     }
200 
201     mpISVCallBacks = (OMX_CALLBACKTYPE *)calloc(1, sizeof(OMX_CALLBACKTYPE));
202     if (!mpISVCallBacks) {
203         ALOGE("%s: failed to alloc isv callbacks", __func__);
204         return NULL;
205     }
206     mpISVCallBacks->EventHandler = EventHandler;
207     mpISVCallBacks->EmptyBufferDone = pCallBacks->EmptyBufferDone;
208     mpISVCallBacks->FillBufferDone = FillBufferDone;
209     return mpISVCallBacks;
210 }
211 
SendCommand(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_COMMANDTYPE Cmd,OMX_IN OMX_U32 nParam1,OMX_IN OMX_PTR pCmdData)212 OMX_ERRORTYPE ISVComponent::SendCommand(
213     OMX_IN  OMX_HANDLETYPE hComponent,
214     OMX_IN  OMX_COMMANDTYPE Cmd,
215     OMX_IN  OMX_U32 nParam1,
216     OMX_IN  OMX_PTR pCmdData)
217 {
218     GET_ISVOMX_COMPONENT(hComponent);
219 
220     return pComp->ISV_SendCommand(Cmd, nParam1, pCmdData);
221 }
222 
ISV_SendCommand(OMX_IN OMX_COMMANDTYPE Cmd,OMX_IN OMX_U32 nParam1,OMX_IN OMX_PTR pCmdData)223 OMX_ERRORTYPE ISVComponent::ISV_SendCommand(
224     OMX_IN  OMX_COMMANDTYPE Cmd,
225     OMX_IN  OMX_U32 nParam1,
226     OMX_IN  OMX_PTR pCmdData)
227 {
228     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: Cmd index 0x%08x, nParam1 %d", __func__, Cmd, nParam1);
229 
230     if (mVPPEnabled && mVPPOn) {
231         if ((Cmd == OMX_CommandFlush && (nParam1 == kPortIndexOutput || nParam1 == OMX_ALL))
232                 || (Cmd == OMX_CommandStateSet && nParam1 == OMX_StateIdle)
233                 || (Cmd == OMX_CommandPortDisable && nParam1 == 1)) {
234             ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: receive flush command, notify vpp thread to flush(Seek begin)", __func__);
235             mVPPFlushing = true;
236             mProcThread->notifyFlush();
237         }
238     }
239 
240     return OMX_SendCommand(mComponent, Cmd, nParam1, pCmdData);
241 }
242 
GetParameter(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_INDEXTYPE nParamIndex,OMX_INOUT OMX_PTR pComponentParameterStructure)243 OMX_ERRORTYPE ISVComponent::GetParameter(
244     OMX_IN  OMX_HANDLETYPE hComponent,
245     OMX_IN  OMX_INDEXTYPE nParamIndex,
246     OMX_INOUT OMX_PTR pComponentParameterStructure)
247 {
248     GET_ISVOMX_COMPONENT(hComponent);
249 
250     return pComp->ISV_GetParameter(nParamIndex, pComponentParameterStructure);
251 }
252 
ISV_GetParameter(OMX_IN OMX_INDEXTYPE nParamIndex,OMX_INOUT OMX_PTR pComponentParameterStructure)253 OMX_ERRORTYPE ISVComponent::ISV_GetParameter(
254     OMX_IN  OMX_INDEXTYPE nParamIndex,
255     OMX_INOUT OMX_PTR pComponentParameterStructure)
256 {
257     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nParamIndex);
258 
259     OMX_ERRORTYPE err = OMX_GetParameter(mComponent, nParamIndex, pComponentParameterStructure);
260 
261     if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) {
262         OMX_PARAM_PORTDEFINITIONTYPE *def =
263             static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(pComponentParameterStructure);
264 
265         if (nParamIndex == OMX_IndexParamPortDefinition
266                 && def->nPortIndex == kPortIndexOutput) {
267             ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: orignal bufferCountActual %d, bufferCountMin %d",  __func__, def->nBufferCountActual, def->nBufferCountMin);
268 #ifndef TARGET_VPP_USE_GEN
269             //FIXME: THIS IS A HACK!! Request NV12 buffer for YV12 format
270             //because VSP only support NV12 output
271             OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video;
272             if ((video_def->eColorFormat == VA_FOURCC_YV12) ||
273                 (video_def->eColorFormat == HAL_PIXEL_FORMAT_INTEL_YV12)) {
274                 //FIXME workaround Disable ISV for YV12 input
275                 mVPPEnabled = false;
276                 ALOGI("%s: Disable ISV for YV12 input. mVPPEnabled %d", __func__, mVPPEnabled);
277             } else {
278                 //FIXME workaround avc low resolution playback
279                 def->nBufferCountActual += mNumISVBuffers + 9;
280                 def->nBufferCountMin += mNumISVBuffers + 9;
281             }
282 #endif
283         }
284     }
285 
286     return err;
287 }
288 
SetParameter(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_INDEXTYPE nIndex,OMX_IN OMX_PTR pComponentParameterStructure)289 OMX_ERRORTYPE ISVComponent::SetParameter(
290     OMX_IN  OMX_HANDLETYPE hComponent,
291     OMX_IN  OMX_INDEXTYPE nIndex,
292     OMX_IN  OMX_PTR pComponentParameterStructure)
293 {
294     GET_ISVOMX_COMPONENT(hComponent);
295 
296     return pComp->ISV_SetParameter(nIndex, pComponentParameterStructure);
297 }
298 
ISV_SetParameter(OMX_IN OMX_INDEXTYPE nIndex,OMX_IN OMX_PTR pComponentParameterStructure)299 OMX_ERRORTYPE ISVComponent::ISV_SetParameter(
300     OMX_IN  OMX_INDEXTYPE nIndex,
301     OMX_IN  OMX_PTR pComponentParameterStructure)
302 {
303     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex);
304 
305     if (nIndex == static_cast<OMX_INDEXTYPE>(OMX_IndexExtSetISVMode)) {
306         ISV_MODE* def = static_cast<ISV_MODE*>(pComponentParameterStructure);
307 
308         if (*def == ISV_AUTO) {
309             mVPPEnabled = true;
310             ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPPEnabled -->true", __func__);
311 #ifndef TARGET_VPP_USE_GEN
312             if (mVPPOn) {
313                 uint32_t number = MIN_INPUT_NUM + MIN_OUTPUT_NUM;
314                 OMX_INDEXTYPE index;
315                 status_t error =
316                     OMX_GetExtensionIndex(
317                             mComponent,
318                             (OMX_STRING)"OMX.Intel.index.vppBufferNum",
319                             &index);
320                 if (error == OK) {
321                     error = OMX_SetParameter(mComponent, index, (OMX_PTR)&number);
322                 } else {
323                     // ingore this error
324                     ALOGW("Get vpp number index failed");
325                 }
326             }
327 #endif
328         } else if (*def == ISV_DISABLE)
329             mVPPEnabled = false;
330         return OMX_ErrorNone;
331     }
332 
333     // before setting param to real omx component, firstly set to media resource manager
334     OMX_ERRORTYPE err = g_mrm_omx_adaptor->MRM_OMX_SetParameter(mComponent,
335                                                                 nIndex,
336                                                                 pComponentParameterStructure);
337     if (err == OMX_ErrorInsufficientResources) {
338         return OMX_ErrorInsufficientResources;
339     }
340 
341     err = OMX_SetParameter(mComponent, nIndex, pComponentParameterStructure);
342     if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) {
343         if (nIndex == OMX_IndexParamPortDefinition) {
344             OMX_PARAM_PORTDEFINITIONTYPE *def =
345                 static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(pComponentParameterStructure);
346 
347             if (def->nPortIndex == kPortIndexOutput) {
348                 //set the buffer count we should fill to decoder before feed buffer to VPP
349                 mNumDecoderBuffersBak = mNumDecoderBuffers = def->nBufferCountActual - MIN_OUTPUT_NUM - UNDEQUEUED_NUM;
350                 mOutputDecoderBufferNum = 0;
351                 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video;
352 
353                 //FIXME: init itself here
354                 if (mWidth != video_def->nFrameWidth
355                         || mHeight != video_def->nFrameHeight) {
356                     deinit();
357                     if (STATUS_OK == init(video_def->nFrameWidth, video_def->nFrameHeight)) {
358                         mWidth = video_def->nFrameWidth;
359                         mHeight = video_def->nFrameHeight;
360                     }
361                 }
362                 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: def->nBufferCountActual %d, mNumDecoderBuffersBak %d", __func__,
363                         def->nBufferCountActual, mNumDecoderBuffersBak);
364                 if (mISVBufferManager != NULL && OK != mISVBufferManager->setBufferCount(def->nBufferCountActual)) {
365                     ALOGE("%s: failed to set ISV buffer count, set VPPEnabled -->false", __func__);
366                     mVPPEnabled = false;
367                 }
368                 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: video frame width %d, height %d",  __func__,
369                         video_def->nFrameWidth, video_def->nFrameHeight);
370             }
371 
372             if (def->nPortIndex == kPortIndexInput) {
373                 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video;
374 
375                 if (mProcThread != NULL)
376                     mProcThread->configFRC(video_def->xFramerate);
377             }
378         }
379 
380         if (mUseAndroidNativeBuffer
381                 && nIndex == static_cast<OMX_INDEXTYPE>(mUseAndroidNativeBufferIndex)) {
382             UseAndroidNativeBufferParams *def =
383                 static_cast<UseAndroidNativeBufferParams*>(pComponentParameterStructure);
384 
385             if (mISVBufferManager != NULL && OK != mISVBufferManager->useBuffer(def->nativeBuffer)) {
386                     ALOGE("%s: failed to register graphic buffers to ISV, set mVPPEnabled -->false", __func__);
387                     mVPPEnabled = false;
388             }
389         }
390 
391         if (nIndex == static_cast<OMX_INDEXTYPE>(mStoreMetaDataInBuffersIndex)) {
392             StoreMetaDataInBuffersParams *params = static_cast<StoreMetaDataInBuffersParams*>(pComponentParameterStructure);
393             if (params->nPortIndex == kPortIndexOutput) {
394                 if (mISVBufferManager != NULL) {
395                     bool bMetaDataMode = params->bStoreMetaData == OMX_TRUE;
396                     mISVBufferManager->setMetaDataMode(bMetaDataMode);
397                 } else {
398                     ALOGE("%s: falied to set Meta Data Mode ", __func__);
399                 }
400             }
401             ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: receive ISVStoreMetaDataInBuffers mISVWorkMode %d", __func__, (params->bStoreMetaData == OMX_TRUE));
402         }
403     }
404     return err;
405 }
406 
GetConfig(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_INDEXTYPE nIndex,OMX_INOUT OMX_PTR pComponentConfigStructure)407 OMX_ERRORTYPE ISVComponent::GetConfig(
408     OMX_IN  OMX_HANDLETYPE hComponent,
409     OMX_IN  OMX_INDEXTYPE nIndex,
410     OMX_INOUT OMX_PTR pComponentConfigStructure)
411 {
412     GET_ISVOMX_COMPONENT(hComponent);
413 
414     return pComp->ISV_GetConfig(nIndex, pComponentConfigStructure);
415 }
416 
ISV_GetConfig(OMX_IN OMX_INDEXTYPE nIndex,OMX_INOUT OMX_PTR pComponentConfigStructure)417 OMX_ERRORTYPE ISVComponent::ISV_GetConfig(
418     OMX_IN  OMX_INDEXTYPE nIndex,
419     OMX_INOUT OMX_PTR pComponentConfigStructure)
420 {
421     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex);
422 
423     OMX_ERRORTYPE err = OMX_GetConfig(mComponent, nIndex, pComponentConfigStructure);
424     if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) {
425         if (nIndex == OMX_IndexConfigCommonOutputCrop) {
426             OMX_CONFIG_RECTTYPE *rect = static_cast<OMX_CONFIG_RECTTYPE*>(pComponentConfigStructure);
427             if (rect->nPortIndex == kPortIndexOutput &&
428                     rect->nWidth < mWidth &&
429                     rect->nHeight < mHeight) {
430                 mISVBufferManager->setBuffersFlag(ISVBuffer::ISV_BUFFER_NEED_CLEAR);
431                 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mark all buffers need clear", __func__);
432             }
433         }
434     }
435     return err;
436 }
437 
SetConfig(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_INDEXTYPE nIndex,OMX_IN OMX_PTR pComponentConfigStructure)438 OMX_ERRORTYPE ISVComponent::SetConfig(
439     OMX_IN  OMX_HANDLETYPE hComponent,
440     OMX_IN  OMX_INDEXTYPE nIndex,
441     OMX_IN  OMX_PTR pComponentConfigStructure)
442 {
443     GET_ISVOMX_COMPONENT(hComponent);
444 
445     return pComp->ISV_SetConfig(nIndex, pComponentConfigStructure);
446 }
447 
ISV_SetConfig(OMX_IN OMX_INDEXTYPE nIndex,OMX_IN OMX_PTR pComponentConfigStructure)448 OMX_ERRORTYPE ISVComponent::ISV_SetConfig(
449     OMX_IN  OMX_INDEXTYPE nIndex,
450     OMX_IN  OMX_PTR pComponentConfigStructure)
451 {
452     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex);
453 
454     if (nIndex == static_cast<OMX_INDEXTYPE>(OMX_IndexConfigAutoFramerateConversion)) {
455         OMX_CONFIG_BOOLEANTYPE *config = static_cast<OMX_CONFIG_BOOLEANTYPE*>(pComponentConfigStructure);
456         if (config->bEnabled) {
457             mVPPEnabled = true;
458             ALOGI("%s: mVPPEnabled=true", __func__);
459         } else {
460             mVPPEnabled = false;
461             ALOGI("%s: mVPPEnabled=false", __func__);
462         }
463         return OMX_ErrorNone;
464     }
465 
466     return OMX_SetConfig(mComponent, nIndex, pComponentConfigStructure);
467 }
468 
GetExtensionIndex(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_STRING cParameterName,OMX_OUT OMX_INDEXTYPE * pIndexType)469 OMX_ERRORTYPE ISVComponent::GetExtensionIndex(
470     OMX_IN  OMX_HANDLETYPE hComponent,
471     OMX_IN  OMX_STRING cParameterName,
472     OMX_OUT OMX_INDEXTYPE* pIndexType)
473 {
474     GET_ISVOMX_COMPONENT(hComponent);
475 
476     return pComp->ISV_GetExtensionIndex(cParameterName, pIndexType);
477 }
478 
ISV_GetExtensionIndex(OMX_IN OMX_STRING cParameterName,OMX_OUT OMX_INDEXTYPE * pIndexType)479 OMX_ERRORTYPE ISVComponent::ISV_GetExtensionIndex(
480     OMX_IN  OMX_STRING cParameterName,
481     OMX_OUT OMX_INDEXTYPE* pIndexType)
482 {
483     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: cParameterName %s", __func__, cParameterName);
484     if(!strncmp(cParameterName, "OMX.intel.index.SetISVMode", strlen(cParameterName))) {
485         *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtSetISVMode);
486         return OMX_ErrorNone;
487     }
488 
489     OMX_ERRORTYPE err = OMX_GetExtensionIndex(mComponent, cParameterName, pIndexType);
490 
491     if(err == OMX_ErrorNone &&
492             !strncmp(cParameterName, "OMX.google.android.index.useAndroidNativeBuffer2", strlen(cParameterName)))
493         mUseAndroidNativeBuffer2 = true;
494 
495     if(err == OMX_ErrorNone &&
496             !strncmp(cParameterName, "OMX.google.android.index.useAndroidNativeBuffer", strlen(cParameterName))) {
497         mUseAndroidNativeBuffer = true;
498         mUseAndroidNativeBufferIndex = static_cast<uint32_t>(*pIndexType);
499     }
500 
501     if(err == OMX_ErrorNone &&
502             !strncmp(cParameterName, "OMX.google.android.index.storeMetaDataInBuffers", strlen(cParameterName))) {
503         mStoreMetaDataInBuffersIndex = static_cast<uint32_t>(*pIndexType);
504         ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: storeMetaDataInBuffersIndex 0x%08x return %d", __func__, mStoreMetaDataInBuffersIndex, err);
505     }
506     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: cParameterName %s, nIndex 0x%08x", __func__,
507             cParameterName, *pIndexType);
508     return err;
509 }
510 
GetState(OMX_IN OMX_HANDLETYPE hComponent,OMX_OUT OMX_STATETYPE * pState)511 OMX_ERRORTYPE ISVComponent::GetState(
512     OMX_IN  OMX_HANDLETYPE hComponent,
513     OMX_OUT OMX_STATETYPE* pState)
514 {
515     GET_ISVOMX_COMPONENT(hComponent);
516 
517     return pComp->ISV_GetState(pState);
518 }
519 
ISV_GetState(OMX_OUT OMX_STATETYPE * pState)520 OMX_ERRORTYPE ISVComponent::ISV_GetState(
521     OMX_OUT OMX_STATETYPE* pState)
522 {
523     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
524 
525     return OMX_GetState(mComponent, pState);
526 }
527 
UseBuffer(OMX_IN OMX_HANDLETYPE hComponent,OMX_INOUT OMX_BUFFERHEADERTYPE ** ppBufferHdr,OMX_IN OMX_U32 nPortIndex,OMX_IN OMX_PTR pAppPrivate,OMX_IN OMX_U32 nSizeBytes,OMX_IN OMX_U8 * pBuffer)528 OMX_ERRORTYPE ISVComponent::UseBuffer(
529     OMX_IN OMX_HANDLETYPE hComponent,
530     OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
531     OMX_IN OMX_U32 nPortIndex,
532     OMX_IN OMX_PTR pAppPrivate,
533     OMX_IN OMX_U32 nSizeBytes,
534     OMX_IN OMX_U8 *pBuffer)
535 {
536     GET_ISVOMX_COMPONENT(hComponent);
537 
538     return pComp->ISV_UseBuffer(ppBufferHdr, nPortIndex,
539                                  pAppPrivate, nSizeBytes, pBuffer);
540 }
541 
ISV_UseBuffer(OMX_INOUT OMX_BUFFERHEADERTYPE ** ppBufferHdr,OMX_IN OMX_U32 nPortIndex,OMX_IN OMX_PTR pAppPrivate,OMX_IN OMX_U32 nSizeBytes,OMX_IN OMX_U8 * pBuffer)542 OMX_ERRORTYPE ISVComponent::ISV_UseBuffer(
543     OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
544     OMX_IN OMX_U32 nPortIndex,
545     OMX_IN OMX_PTR pAppPrivate,
546     OMX_IN OMX_U32 nSizeBytes,
547     OMX_IN OMX_U8 *pBuffer)
548 {
549     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
550 
551     OMX_ERRORTYPE err = OMX_UseBuffer(mComponent, ppBufferHdr, nPortIndex,
552             pAppPrivate, nSizeBytes, pBuffer);
553 #ifndef USE_IVP
554     if(err == OMX_ErrorNone
555             && mVPPEnabled
556             && mVPPOn
557             && nPortIndex == kPortIndexOutput
558             /*&& mUseAndroidNativeBuffer2*/) {
559         if (mISVBufferManager != NULL) {
560             if (OK != mISVBufferManager->useBuffer(reinterpret_cast<unsigned long>(pBuffer))) {
561                 ALOGE("%s: failed to register graphic buffers to ISV, set mVPPEnabled -->false", __func__);
562                 mVPPEnabled = false;
563             } else
564                 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPP useBuffer success. buffer handle %p", __func__, pBuffer);
565         }
566     }
567 #endif
568     return err;
569 }
570 
AllocateBuffer(OMX_IN OMX_HANDLETYPE hComponent,OMX_INOUT OMX_BUFFERHEADERTYPE ** ppBuffer,OMX_IN OMX_U32 nPortIndex,OMX_IN OMX_PTR pAppPrivate,OMX_IN OMX_U32 nSizeBytes)571 OMX_ERRORTYPE ISVComponent::AllocateBuffer(
572     OMX_IN OMX_HANDLETYPE hComponent,
573     OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
574     OMX_IN OMX_U32 nPortIndex,
575     OMX_IN OMX_PTR pAppPrivate,
576     OMX_IN OMX_U32 nSizeBytes)
577 {
578     GET_ISVOMX_COMPONENT(hComponent);
579 
580     return pComp->ISV_AllocateBuffer(ppBuffer, nPortIndex,
581                                       pAppPrivate, nSizeBytes);
582 }
583 
ISV_AllocateBuffer(OMX_INOUT OMX_BUFFERHEADERTYPE ** ppBuffer,OMX_IN OMX_U32 nPortIndex,OMX_IN OMX_PTR pAppPrivate,OMX_IN OMX_U32 nSizeBytes)584 OMX_ERRORTYPE ISVComponent::ISV_AllocateBuffer(
585     OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
586     OMX_IN OMX_U32 nPortIndex,
587     OMX_IN OMX_PTR pAppPrivate,
588     OMX_IN OMX_U32 nSizeBytes)
589 {
590     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
591 
592     return OMX_AllocateBuffer(mComponent, ppBuffer, nPortIndex,
593                                       pAppPrivate, nSizeBytes);
594 }
595 
FreeBuffer(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_U32 nPortIndex,OMX_IN OMX_BUFFERHEADERTYPE * pBuffer)596 OMX_ERRORTYPE ISVComponent::FreeBuffer(
597     OMX_IN  OMX_HANDLETYPE hComponent,
598     OMX_IN  OMX_U32 nPortIndex,
599     OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
600 {
601     GET_ISVOMX_COMPONENT(hComponent);
602 
603     return pComp->ISV_FreeBuffer(nPortIndex, pBuffer);
604 }
605 
ISV_FreeBuffer(OMX_IN OMX_U32 nPortIndex,OMX_IN OMX_BUFFERHEADERTYPE * pBuffer)606 OMX_ERRORTYPE ISVComponent::ISV_FreeBuffer(
607     OMX_IN  OMX_U32 nPortIndex,
608     OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
609 {
610     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: pBuffer %p", __func__, pBuffer);
611 
612     if(mVPPEnabled && mVPPOn
613             && nPortIndex == kPortIndexOutput) {
614         if (mISVBufferManager != NULL && OK != mISVBufferManager->freeBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer)))
615             ALOGW("%s: pBuffer %p has not been registered into ISV", __func__, pBuffer);
616     }
617     return OMX_FreeBuffer(mComponent, nPortIndex, pBuffer);
618 }
619 
EmptyThisBuffer(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_BUFFERHEADERTYPE * pBuffer)620 OMX_ERRORTYPE ISVComponent::EmptyThisBuffer(
621     OMX_IN  OMX_HANDLETYPE hComponent,
622     OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
623 {
624     GET_ISVOMX_COMPONENT(hComponent);
625 
626     return pComp->ISV_EmptyThisBuffer(pBuffer);
627 }
628 
ISV_EmptyThisBuffer(OMX_IN OMX_BUFFERHEADERTYPE * pBuffer)629 OMX_ERRORTYPE ISVComponent::ISV_EmptyThisBuffer(
630     OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
631 {
632     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: pBuffer %p", __func__, pBuffer);
633 
634     return OMX_EmptyThisBuffer(mComponent, pBuffer);
635 }
636 
FillThisBuffer(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_BUFFERHEADERTYPE * pBuffer)637 OMX_ERRORTYPE ISVComponent::FillThisBuffer(
638     OMX_IN  OMX_HANDLETYPE hComponent,
639     OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
640 {
641     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry.", __func__);
642     GET_ISVOMX_COMPONENT(hComponent);
643 
644     return pComp->ISV_FillThisBuffer(pBuffer);
645 }
646 
ISV_FillThisBuffer(OMX_IN OMX_BUFFERHEADERTYPE * pBuffer)647 OMX_ERRORTYPE ISVComponent::ISV_FillThisBuffer(
648     OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
649 {
650     if(!mVPPEnabled || !mVPPOn)
651         return OMX_FillThisBuffer(mComponent, pBuffer);
652 
653     ISVBuffer* isvBuffer = NULL;
654 
655     if (mISVBufferManager != NULL) {
656         isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer));
657         if (isvBuffer == NULL) {
658             ALOGE("%s: failed to map ISVBuffer, set mVPPEnabled -->false", __func__);
659             mVPPEnabled = false;
660             return OMX_FillThisBuffer(mComponent, pBuffer);
661         }
662 
663         if (OK != isvBuffer->initBufferInfo(mHackFormat)) {
664             ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: isvBuffer %p failed to initBufferInfo", __func__, isvBuffer);
665             mVPPEnabled = false;
666             return OMX_FillThisBuffer(mComponent, pBuffer);
667         }
668     }
669 
670     if (mNumDecoderBuffers > 0) {
671         Mutex::Autolock autoLock(mDecoderBufLock);
672         mNumDecoderBuffers--;
673         ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: fill pBuffer %p to the decoder, decoder still need extra %d buffers", __func__,
674                 pBuffer, mNumDecoderBuffers);
675 
676         if (isvBuffer != NULL)
677             isvBuffer->clearIfNeed();
678 
679         return OMX_FillThisBuffer(mComponent, pBuffer);
680     }
681     mProcThread->addOutput(pBuffer);
682 
683     return OMX_ErrorNone;
684 }
685 
FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent,OMX_OUT OMX_PTR pAppData,OMX_OUT OMX_BUFFERHEADERTYPE * pBuffer)686 OMX_ERRORTYPE ISVComponent::FillBufferDone(
687         OMX_OUT OMX_HANDLETYPE hComponent,
688         OMX_OUT OMX_PTR pAppData,
689         OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
690 {
691     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry. ISV component num %d, component handle %p on index 0", __func__,
692             g_isv_components.size(),
693             g_isv_components.itemAt(0));
694     for (OMX_U32 i = 0; i < g_isv_components.size(); i++) {
695         if (static_cast<OMX_HANDLETYPE>(g_isv_components.itemAt(i)->mComponent) == hComponent)
696             return g_isv_components.itemAt(i)->ISV_FillBufferDone(hComponent, pAppData, pBuffer);
697     }
698     return OMX_ErrorUndefined;
699 }
700 
ISV_FillBufferDone(OMX_OUT OMX_HANDLETYPE __maybe_unused hComponent,OMX_OUT OMX_PTR pAppData,OMX_OUT OMX_BUFFERHEADERTYPE * pBuffer)701 OMX_ERRORTYPE ISVComponent::ISV_FillBufferDone(
702         OMX_OUT OMX_HANDLETYPE __maybe_unused hComponent,
703         OMX_OUT OMX_PTR pAppData,
704         OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
705 {
706     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: %p <== buffer_handle_t %p. mVPPEnabled %d, mVPPOn %d", __func__,
707             pBuffer, pBuffer->pBuffer, mVPPEnabled, mVPPOn);
708     if (!mpCallBacks) {
709         ALOGE("%s: no call back functions were registered.", __func__);
710         return OMX_ErrorUndefined;
711     }
712 
713     if(!mVPPEnabled || !mVPPOn || mVPPFlushing || pBuffer->nFilledLen == 0) {
714         ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBufferDone pBuffer %p, timeStamp %.2f ms", __func__, pBuffer, pBuffer->nTimeStamp/1E3);
715         return mpCallBacks->FillBufferDone(&mBaseComponent, pAppData, pBuffer);
716     }
717 
718     if (mOutputCropChanged && mISVBufferManager != NULL) {
719         ISVBuffer* isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer));
720         if (isvBuffer != NULL)
721             isvBuffer->setFlag(ISVBuffer::ISV_BUFFER_CROP_CHANGED);
722         mOutputCropChanged = false;
723     }
724 
725     if ((mWidth > FLUSH_WIDTH) && (mHeight > FLUSH_HEIGHT) &&
726         (pBuffer->nFilledLen != 0) && (mOutputDecoderBufferNum < OUTPUT_STARTUP_DEC_BUF_NUM)) {
727         Mutex::Autolock autoLock(mDecoderBufLock);
728         // take one buffer from decoder loop here. Fill one buffer to the loop by mNumDecoderBuffers++
729         mNumDecoderBuffers++;
730         mOutputDecoderBufferNum++;
731         ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: return %d decoder output Buffer, mNumDecoderBuffers get %d input buffer",
732                 __func__, mOutputDecoderBufferNum, mNumDecoderBuffers);
733         return mpCallBacks->FillBufferDone(&mBaseComponent, pAppData, pBuffer);
734     }
735 
736     mProcThread->addInput(pBuffer);
737 
738     return OMX_ErrorNone;
739 }
740 
EventHandler(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)741 OMX_ERRORTYPE ISVComponent::EventHandler(
742         OMX_IN OMX_HANDLETYPE hComponent,
743         OMX_IN OMX_PTR pAppData,
744         OMX_IN OMX_EVENTTYPE eEvent,
745         OMX_IN OMX_U32 nData1,
746         OMX_IN OMX_U32 nData2,
747         OMX_IN OMX_PTR pEventData)
748 {
749     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry. ISV component num %d, component handle %p on index 0", __func__,
750             g_isv_components.size(),
751             g_isv_components.itemAt(0));
752     for (OMX_U32 i = 0; i < g_isv_components.size(); i++) {
753         if (static_cast<OMX_HANDLETYPE>(g_isv_components.itemAt(i)->mComponent) == hComponent)
754             return g_isv_components.itemAt(i)->ISV_EventHandler(hComponent, pAppData, eEvent, nData1, nData2, pEventData);
755     }
756     return OMX_ErrorUndefined;
757 }
758 
ISV_EventHandler(OMX_IN OMX_HANDLETYPE __maybe_unused hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)759 OMX_ERRORTYPE ISVComponent::ISV_EventHandler(
760         OMX_IN OMX_HANDLETYPE __maybe_unused hComponent,
761         OMX_IN OMX_PTR pAppData,
762         OMX_IN OMX_EVENTTYPE eEvent,
763         OMX_IN OMX_U32 nData1,
764         OMX_IN OMX_U32 nData2,
765         OMX_IN OMX_PTR pEventData)
766 {
767     if (!mpCallBacks) {
768         ALOGE("%s: no call back functions were registered.", __func__);
769         return OMX_ErrorUndefined;
770     }
771 
772     if(!mVPPEnabled || !mVPPOn)
773         return mpCallBacks->EventHandler(&mBaseComponent, pAppData, eEvent, nData1, nData2, pEventData);
774 
775     switch (eEvent) {
776         case OMX_EventCmdComplete:
777         {
778             ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: OMX_EventCmdComplete Cmd type 0x%08x, data2 %d", __func__,
779                     nData1, nData2);
780             if (((OMX_COMMANDTYPE)nData1 == OMX_CommandFlush && (nData2 == kPortIndexOutput || nData2 == OMX_ALL))
781                 || ((OMX_COMMANDTYPE)nData1 == OMX_CommandStateSet && nData2 == OMX_StateIdle)
782                 || ((OMX_COMMANDTYPE)nData1 == OMX_CommandPortDisable && nData2 == 1)) {
783                 mProcThread->waitFlushFinished();
784                 mVPPFlushing = false;
785                 mNumDecoderBuffers = mNumDecoderBuffersBak;
786                 mOutputDecoderBufferNum = 0;
787             }
788             break;
789         }
790 
791         case OMX_EventError:
792         {
793             //do we need do anything here?
794             ALOGE("%s: ERROR(0x%08x, %d)", __func__, nData1, nData2);
795             //mProcThread->flush();
796             break;
797         }
798 
799         case OMX_EventPortSettingsChanged:
800         {
801             if (nData1 == kPortIndexOutput && nData2 == OMX_IndexConfigCommonOutputCrop) {
802                 ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: output crop changed", __func__);
803                 mOutputCropChanged = true;
804                 return OMX_ErrorNone;
805             } else if (nData1 == kPortIndexOutput && nData2 == OMX_IndexParamPortDefinition) {
806                 ALOGI("%s: output format changed. ISV flush buffers", __func__);
807                 mProcThread->notifyFlush();
808             }
809             break;
810         }
811 
812         default:
813         {
814             ALOGD_IF(
815                 ISV_COMPONENT_DEBUG, "%s: EVENT(%d, %" PRId32 ", %" PRId32 ")",
816                 __func__, eEvent, nData1, nData2);
817             break;
818         }
819     }
820     return mpCallBacks->EventHandler(&mBaseComponent, pAppData, eEvent, nData1, nData2, pEventData);
821 }
822 
SetCallbacks(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_CALLBACKTYPE * pCallbacks,OMX_IN OMX_PTR pAppData)823 OMX_ERRORTYPE ISVComponent::SetCallbacks(
824     OMX_IN  OMX_HANDLETYPE hComponent,
825     OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
826     OMX_IN  OMX_PTR pAppData)
827 {
828     GET_ISVOMX_COMPONENT(hComponent);
829 
830     return pComp->ISV_SetCallbacks(pCallbacks, pAppData);
831 }
832 
ISV_SetCallbacks(OMX_IN OMX_CALLBACKTYPE * pCallbacks,OMX_IN OMX_PTR pAppData)833 OMX_ERRORTYPE ISVComponent::ISV_SetCallbacks(
834     OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
835     OMX_IN  OMX_PTR pAppData)
836 {
837     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
838 
839     if (mVPPEnabled && mVPPOn) {
840         if (mpISVCallBacks == NULL) {
841             mpISVCallBacks = (OMX_CALLBACKTYPE *)calloc(1, sizeof(OMX_CALLBACKTYPE));
842             if (!mpISVCallBacks) {
843                 ALOGE("%s: failed to alloc isv callbacks", __func__);
844                 return OMX_ErrorUndefined;
845             }
846         }
847         mpISVCallBacks->EventHandler = EventHandler;
848         mpISVCallBacks->EmptyBufferDone = pCallbacks->EmptyBufferDone;
849         mpISVCallBacks->FillBufferDone = FillBufferDone;
850         mpCallBacks = pCallbacks;
851         return mComponent->SetCallbacks(mComponent, mpISVCallBacks, pAppData);
852     }
853     return mComponent->SetCallbacks(mComponent, pCallbacks, pAppData);
854 }
855 
ComponentRoleEnum(OMX_IN OMX_HANDLETYPE hComponent,OMX_OUT OMX_U8 * cRole,OMX_IN OMX_U32 nIndex)856 OMX_ERRORTYPE ISVComponent::ComponentRoleEnum(
857     OMX_IN OMX_HANDLETYPE hComponent,
858     OMX_OUT OMX_U8 *cRole,
859     OMX_IN OMX_U32 nIndex)
860 {
861     GET_ISVOMX_COMPONENT(hComponent);
862 
863     return pComp->ISV_ComponentRoleEnum(cRole, nIndex);
864 }
865 
ISV_ComponentRoleEnum(OMX_OUT OMX_U8 * cRole,OMX_IN OMX_U32 nIndex)866 OMX_ERRORTYPE ISVComponent::ISV_ComponentRoleEnum(
867     OMX_OUT OMX_U8 *cRole,
868     OMX_IN OMX_U32 nIndex)
869 {
870     ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
871 
872     return mComponent->ComponentRoleEnum(mComponent, cRole, nIndex);
873 }
874 
875 
SetTypeHeader(OMX_PTR type,OMX_U32 size)876 void ISVComponent::SetTypeHeader(OMX_PTR type, OMX_U32 size)
877 {
878     OMX_U32 *nsize;
879     OMX_VERSIONTYPE *nversion;
880 
881     if (!type)
882         return;
883 
884     nsize = (OMX_U32 *)type;
885     nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
886 
887     *nsize = size;
888     nversion->nVersion = OMX_SPEC_VERSION;
889 }
890 
891 
ISVProcThreadObserver(OMX_COMPONENTTYPE * pBaseComponent,OMX_COMPONENTTYPE * pComponent,OMX_CALLBACKTYPE * pCallBacks,sp<ISVBufferManager> bufferManager)892 ISVProcThreadObserver::ISVProcThreadObserver(
893         OMX_COMPONENTTYPE *pBaseComponent,
894         OMX_COMPONENTTYPE *pComponent,
895         OMX_CALLBACKTYPE *pCallBacks,
896         sp<ISVBufferManager> bufferManager)
897     :   mBaseComponent(pBaseComponent),
898         mComponent(pComponent),
899         mpCallBacks(pCallBacks),
900         mISVBufferManager(bufferManager)
901 {
902     ALOGV("VPPProcThreadObserver!");
903 }
904 
~ISVProcThreadObserver()905 ISVProcThreadObserver::~ISVProcThreadObserver()
906 {
907     ALOGV("~VPPProcThreadObserver!");
908     mBaseComponent = NULL;
909     mComponent = NULL;
910     mpCallBacks = NULL;
911 }
912 
releaseBuffer(PORT_INDEX index,OMX_BUFFERHEADERTYPE * pBuffer,bool bFLush)913 OMX_ERRORTYPE ISVProcThreadObserver::releaseBuffer(PORT_INDEX index, OMX_BUFFERHEADERTYPE* pBuffer, bool bFLush)
914 {
915     if (!mBaseComponent || !mComponent || !mpCallBacks)
916         return OMX_ErrorUndefined;
917 
918     OMX_ERRORTYPE err = OMX_ErrorNone;
919     if (bFLush) {
920         if(index == kPortIndexOutput) {
921             pBuffer->nFilledLen = 0;
922             pBuffer->nOffset = 0;
923             pBuffer->nTimeStamp = 0;
924             pBuffer->nFlags = 0;
925         }
926         err = mpCallBacks->FillBufferDone(&mBaseComponent, mBaseComponent->pApplicationPrivate, pBuffer);
927         ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: flush pBuffer %p", __func__, pBuffer);
928         return err;
929     }
930 
931     if (index == kPortIndexInput) {
932         pBuffer->nFilledLen = 0;
933         pBuffer->nOffset = 0;
934         pBuffer->nFlags = 0;
935         pBuffer->nTimeStamp = 0;
936 
937         if (mISVBufferManager != NULL) {
938             ISVBuffer* isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<unsigned long>(pBuffer->pBuffer));
939             if (isvBuffer != NULL)
940                 isvBuffer->clearIfNeed();
941         }
942 
943         err = OMX_FillThisBuffer(mComponent, pBuffer);
944         ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBuffer pBuffer %p", __func__, pBuffer);
945     } else {
946         err = mpCallBacks->FillBufferDone(&mBaseComponent, mBaseComponent->pApplicationPrivate, pBuffer);
947         ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBufferDone pBuffer %p, timeStamp %.2f ms", __func__, pBuffer, pBuffer->nTimeStamp/1E3);
948     }
949 
950     return err;
951 }
952 
reportOutputCrop()953 OMX_ERRORTYPE ISVProcThreadObserver::reportOutputCrop()
954 {
955     if (!mBaseComponent || !mComponent || !mpCallBacks)
956         return OMX_ErrorUndefined;
957 
958     OMX_ERRORTYPE err = OMX_ErrorNone;
959     err = mpCallBacks->EventHandler(&mBaseComponent, mBaseComponent->pApplicationPrivate,
960                                     OMX_EventPortSettingsChanged,
961                                     kPortIndexOutput, OMX_IndexConfigCommonOutputCrop, NULL);
962     return err;
963 }
964