• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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