Home | History | Annotate | Download | only in omx_adaptor
      1 /*
      2  * * Copyright (c) 2015 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 //#define LOG_NDEBUG 0
     19 #define LOG_TAG "MRM_OMX_Adaptor"
     20 
     21 #include <utils/Log.h>
     22 #include <utils/threads.h>
     23 #include "OMX_adaptor.h"
     24 
     25 const char* CODECS_LIMITATION_FILE = "/etc/codec_resources_limitation.xml";
     26 
     27 using namespace android;
     28 
     29 // static member declare
     30 MRM_OMX_Adaptor* MRM_OMX_Adaptor::sInstance = NULL;
     31 Mutex MRM_OMX_Adaptor::sLock;
     32 
     33 typedef enum {
     34     kPortIndexInput  = 0,
     35     kPortIndexOutput = 1
     36 } PORT_INDEX;
     37 
     38 
     39 // case insensitive string finding
     40 static const char* strstri(const char* str, const char* subStr) {
     41     int len = strlen(subStr);
     42     if (len == 0) {
     43         return NULL;
     44     }
     45 
     46     while(*str) {
     47         if(strncasecmp(str, subStr, len) == 0) {
     48             return str;
     49         }
     50         ++str;
     51     }
     52     return NULL;
     53 }
     54 
     55 
     56 //static
     57 MRM_OMX_Adaptor* MRM_OMX_Adaptor::getInstance() {
     58     ALOGV("getInstance()");
     59     Mutex::Autolock lock(sLock);
     60 
     61     if (sInstance == NULL) {
     62         sInstance = new MRM_OMX_Adaptor();
     63     }
     64 
     65     return sInstance;
     66 }
     67 
     68 
     69 OMX_ERRORTYPE MRM_OMX_Adaptor::MRM_OMX_Init(void) {
     70     ALOGV("MRM_OMX_Init");
     71     OMX_ERRORTYPE err = OMX_ErrorNone;
     72     if (mArbitrator != NULL) {
     73         err = (OMX_ERRORTYPE)mArbitrator->Config(CODECS_LIMITATION_FILE);
     74     }
     75     return err;
     76 }
     77 
     78 
     79 OMX_ERRORTYPE MRM_OMX_Adaptor::MRM_OMX_CheckIfFullLoad(OMX_STRING cComponentName) {
     80     ALOGV("MRM_OMX_CheckIfFullLoad");
     81     Mutex::Autolock lock(sLock);
     82 
     83     String8 sComponentName(cComponentName);
     84     AdaptorCodecInfo codecInfo;
     85     ParseCodecInfoFromComponentName(sComponentName.string(), &codecInfo);
     86 
     87     if (codecInfo.isEncoder) {
     88         ALOGV("Checking full load status of encoder.");
     89         if (mArbitrator->CheckIfFullLoad(true/*encoder*/)) {
     90             ALOGV("encoder in full load status. return OMX_ErrorInsufficientResources");
     91             return OMX_ErrorInsufficientResources;
     92         } else {
     93             return OMX_ErrorNone;
     94         }
     95     } else {
     96         ALOGV("Checking full load status of decoder.");
     97         if (mArbitrator->CheckIfFullLoad(false/*decoder*/)) {
     98             ALOGV("decoder in full load status. return OMX_ErrorInsufficientResources");
     99             return OMX_ErrorInsufficientResources;
    100         } else {
    101             return OMX_ErrorNone;
    102         }
    103     }
    104 }
    105 
    106 
    107 void MRM_OMX_Adaptor::MRM_OMX_SetComponent(
    108                           OMX_HANDLETYPE pComponentHandle,
    109                           OMX_STRING cComponentName) {
    110     ALOGV("MRM_OMX_SetComponent: %s", cComponentName);
    111     String8 sComponentName(cComponentName);
    112     ALOGV("pComponentHandle = %p, componentName = %s", pComponentHandle, sComponentName.string());
    113     mComponentNameMap.add(pComponentHandle, sComponentName);
    114 }
    115 
    116 
    117 OMX_ERRORTYPE MRM_OMX_Adaptor::MRM_OMX_SetParameter(
    118                          OMX_HANDLETYPE hComponent,
    119                          OMX_INDEXTYPE nIndex,
    120                          OMX_PTR pComponentParameterStructure) {
    121     ALOGV("MRM_OMX_SetParameter");
    122     ALOGV("hComponent = %p", hComponent);
    123     OMX_ERRORTYPE err = OMX_ErrorNone;
    124 
    125     Mutex::Autolock lock(sLock);
    126 
    127     if (nIndex == OMX_IndexParamPortDefinition) {
    128         OMX_PARAM_PORTDEFINITIONTYPE *def =
    129             static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(pComponentParameterStructure);
    130 
    131         if (def->nPortIndex == kPortIndexInput) {
    132             ALOGV("MRM_OMX_SetParameter for inport param def");
    133             if (mComponentFramerateMap.indexOfKey(hComponent) >= 0) {
    134                 ALOGV("setParameter is called again for component %p inport", hComponent);
    135                 return OMX_ErrorNone;
    136             }
    137 
    138             OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video;
    139             uint frameRate = (uint)(video_def->xFramerate/65536);
    140             ALOGV("frame rate from inport = %d", frameRate);
    141             mComponentFramerateMap.add(hComponent, frameRate);
    142         }
    143 
    144         if (def->nPortIndex == kPortIndexOutput) {
    145             OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video;
    146 
    147             // if setParameter is not first called to this component's outport
    148             // do not try to record its info for the second time
    149             if (mComponentInfoMap.indexOfKey(hComponent) >= 0) {
    150                 ALOGV("setParameter is called again for component %p outport", hComponent);
    151                 return OMX_ErrorNone;
    152             }
    153 
    154             String8 sComponentName = mComponentNameMap.valueFor(hComponent);
    155             ALOGV("component name from component map is %s", sComponentName.string());
    156 
    157             AdaptorCodecInfo codecInfo;
    158             ParseCodecInfoFromComponentName(sComponentName.string(), &codecInfo);
    159 
    160             if (mArbitrator->CheckIfFullLoad(codecInfo.isEncoder)) {
    161                 return OMX_ErrorInsufficientResources;
    162             }
    163 
    164             ResolutionType resolution = Resolution_CIF;
    165             unsigned int height = video_def->nFrameHeight;
    166             ALOGV("video resulotion = %d x %d", video_def->nFrameWidth, video_def->nFrameHeight);
    167             if (height <= 480) {
    168                 resolution = Resolution_480;
    169             } else if (height <= 720) {
    170                 resolution = Resolution_720;
    171             } else if (height <= 1080) {
    172                 resolution = Resolution_1080;
    173             } else if (height <= 1440) {
    174                 resolution = Resolution_2K;
    175             } else if (height <= 2160) {
    176                 resolution = Resolution_4K;
    177             } else {
    178                 ALOGE("resolution > 4K is not supported!");
    179             }
    180             codecInfo.resolution = resolution;
    181 
    182             unsigned int frameRate = 0;
    183             if (mComponentFramerateMap.indexOfKey(hComponent) >= 0) {
    184                 frameRate = mComponentFramerateMap.valueFor(hComponent);
    185             } else {
    186                 ALOGW("frame rate was not set in inport def...");
    187             }
    188 
    189             ALOGV("frame rate from inport def = %d", frameRate);
    190             if ((frameRate > 55) && (frameRate < 65)) {
    191                 frameRate = 60;
    192             // This is a w/a to set default frame rate as 30 in case it is not
    193             // set from framewrok.
    194             } else {
    195                 frameRate = 30;
    196             }
    197             codecInfo.frameRate = frameRate;
    198             err = (OMX_ERRORTYPE)mArbitrator->AddResource(codecInfo.codecType,
    199                                                           codecInfo.isEncoder,
    200                                                           codecInfo.isSecured,
    201                                                           codecInfo.resolution,
    202                                                           codecInfo.frameRate);
    203 
    204             mComponentInfoMap.add(hComponent, codecInfo);
    205         }
    206     }
    207     return err;
    208 }
    209 
    210 
    211 OMX_ERRORTYPE MRM_OMX_Adaptor::MRM_OMX_UseBuffer(
    212                          OMX_HANDLETYPE hComponent,
    213                          OMX_BUFFERHEADERTYPE **ppBufferHdr,
    214                          OMX_U32 nPortIndex,
    215                          OMX_PTR pAppPrivate,
    216                          OMX_U32 nSizeBytes,
    217                          OMX_U8 *pBuffer) {
    218     ALOGV("MRM_OMX_UseBuffer");
    219     if(pBuffer == 0 || ppBufferHdr == 0) {
    220         ALOGV("%s: Null buffer. hComponent:%p, ppBufferHdr:%p, "
    221             "nPortIndex:%d, pAppPrivate:%p, nSizeBytes:%d, pBuffer:%p",
    222             __FUNCTION__,
    223             hComponent,
    224             ppBufferHdr,
    225             nPortIndex,
    226             pAppPrivate,
    227             nSizeBytes,
    228             pBuffer);
    229     }
    230 
    231     OMX_ERRORTYPE err = OMX_ErrorNone;
    232     return err;
    233 }
    234 
    235 
    236 OMX_ERRORTYPE MRM_OMX_Adaptor::MRM_OMX_RemoveComponent(
    237                                    OMX_HANDLETYPE pComponentHandle) {
    238     ALOGV("MRM_OMX_RemoveComponent %p", pComponentHandle);
    239     OMX_ERRORTYPE err = OMX_ErrorNone;
    240 
    241     if (mComponentInfoMap.indexOfKey(pComponentHandle) < 0) {
    242         ALOGE("component %p was not added by setParameter before! something is wrong?", pComponentHandle);
    243         return OMX_ErrorNone; // TODO: change to specific error.
    244     }
    245 
    246     const AdaptorCodecInfo& codecInfo = mComponentInfoMap.valueFor(pComponentHandle);
    247 
    248     err = (OMX_ERRORTYPE)mArbitrator->RemoveResource(codecInfo.codecType,
    249                                                   codecInfo.isEncoder,
    250                                                   codecInfo.isSecured,
    251                                                   codecInfo.resolution,
    252                                                   codecInfo.frameRate);
    253     mComponentInfoMap.removeItem(pComponentHandle);
    254     return err;
    255 }
    256 
    257 
    258 
    259 
    260 void MRM_OMX_Adaptor::ParseCodecInfoFromComponentName(
    261                                          const char* componentName,
    262                                          AdaptorCodecInfo* codecInfo) {
    263     ALOGV("ParseCodecInfoFromComponentName");
    264     ALOGV("componentName = %s", componentName);
    265     bool isSecured = false;
    266     if (strstri(componentName,"SECURE") != NULL) {
    267         isSecured = true;
    268     }
    269     codecInfo->isSecured = isSecured;
    270 
    271     bool isEncoder = false;
    272     if ((strstri(componentName, "ENCODER") != NULL) ||
    273         (strstri(componentName, "sw_ve") != NULL)) {
    274         isEncoder = true;
    275     }
    276     codecInfo->isEncoder = isEncoder;
    277 
    278     CodecType codecType = CODEC_TYPE_MAX;
    279     if (strstri(componentName, "AVC") != NULL) {
    280         codecType = CODEC_TYPE_AVC;
    281     } else if (strstri(componentName, "VP8") != NULL) {
    282         codecType = CODEC_TYPE_VP8;
    283     } else if (strstri(componentName, "VP9") != NULL) {
    284         codecType = CODEC_TYPE_VP9;
    285     } else if (strstri(componentName, "MPEG4") != NULL) {
    286         codecType = CODEC_TYPE_MPEG4;
    287     } else if (strstri(componentName, "MPEG2") != NULL) {
    288         codecType = CODEC_TYPE_MPEG2;
    289     } else if (strstri(componentName, "H263") != NULL) {
    290         codecType = CODEC_TYPE_H263;
    291     } else if (strstri(componentName, "H265") != NULL) {
    292         codecType = CODEC_TYPE_HEVC;
    293     } else if (strstri(componentName, "WMV") != NULL) {
    294         codecType = CODEC_TYPE_WMV;
    295     }
    296     ALOGV("video codec type = %d", codecType);
    297     codecInfo->codecType = codecType;
    298 }
    299 
    300 
    301