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