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