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