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