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