Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      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 #include "sles_allinclusive.h"
     18 
     19 #include <media/stagefright/MediaCodecList.h>
     20 #include <media/stagefright/MediaDefs.h>
     21 #include <media/stagefright/SimpleDecodingSource.h>
     22 
     23 
     24 namespace android {
     25 
     26 // listed in same order as VideoCodecIds[] in file "../devices.c" with ANDROID defined
     27 static const char *kVideoMimeTypes[] = {
     28         MEDIA_MIMETYPE_VIDEO_MPEG2,
     29         MEDIA_MIMETYPE_VIDEO_H263,
     30         MEDIA_MIMETYPE_VIDEO_MPEG4,
     31         MEDIA_MIMETYPE_VIDEO_AVC,
     32         MEDIA_MIMETYPE_VIDEO_VP8,
     33         MEDIA_MIMETYPE_VIDEO_VP9
     34 };
     35 // must == kMaxVideoDecoders
     36 static const size_t kNbVideoMimeTypes = sizeof(kVideoMimeTypes) / sizeof(kVideoMimeTypes[0]);
     37 
     38 // codec capabilities in the following arrays maps to the mime types defined in kVideoMimeTypes
     39 struct CodecCapabilities {
     40     Vector<MediaCodecInfo::ProfileLevel> mProfileLevels;
     41 };
     42 
     43 static CodecCapabilities VideoDecoderCapabilities[kNbVideoMimeTypes];
     44 static XAuint32 VideoDecoderNbProfLevel[kNbVideoMimeTypes];
     45 
     46 static XAuint32 NbSupportedDecoderTypes = 0;
     47 
     48 
     49 XAuint32 convertOpenMaxIlToAl(OMX_U32 ilVideoProfileOrLevel) {
     50     // For video codec profiles and levels, the number of trailing zeroes in OpenMAX IL
     51     // are equal to the matching OpenMAX AL constant value plus 1, for example:
     52     //    XA_VIDEOPROFILE_H263_BACKWARDCOMPATIBLE ((XAuint32) 0x00000003)
     53     //        matches
     54     //    OMX_VIDEO_H263ProfileBackwardCompatible  = 0x04
     55     return (XAuint32) (__builtin_ctz(ilVideoProfileOrLevel) + 1);
     56 }
     57 
     58 
     59 bool android_videoCodec_expose() {
     60     SL_LOGV("android_videoCodec_expose()");
     61 
     62     sp<IMediaCodecList> list = MediaCodecList::getInstance();
     63     if (list == NULL) {
     64         SL_LOGE("could not get MediaCodecList");
     65         return false;
     66     }
     67 
     68     // used to check whether no codecs were found, which is a sign of failure
     69     NbSupportedDecoderTypes = 0;
     70     for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) {
     71         VideoDecoderNbProfLevel[m] = 0;
     72         for (ssize_t index = 0;; ++index) {
     73             index = list->findCodecByType(
     74                     kVideoMimeTypes[m], false /* encoder */, index);
     75             if (index < 0) {
     76                 break;
     77             }
     78 
     79             sp<MediaCodecInfo> info = list->getCodecInfo(index);
     80             if (info == NULL || MediaCodecList::isSoftwareCodec(info->getCodecName())) {
     81                 continue; // HW codec only
     82             }
     83 
     84             sp<MediaCodecInfo::Capabilities> caps = info->getCapabilitiesFor(kVideoMimeTypes[m]);
     85             if (caps == NULL) {
     86                 continue; // this should not happen
     87             }
     88 
     89             // get the number of profiles and levels
     90             Vector<MediaCodecInfo::ProfileLevel> &profileLevels =
     91                 VideoDecoderCapabilities[m].mProfileLevels;
     92             caps->getSupportedProfileLevels(&profileLevels);
     93 #if 0   // Intentionally disabled example of making modifications to profile / level combinations
     94             if (VideoDecoderIds[m] == XA_VIDEOCODEC_AVC) {
     95                 // remove non-core profile / level combinations
     96                 for (size_t i = 0, size = profileLevels.size(); i < size; ) {
     97                     MediaCodecInfo::ProfileLevel profileLevel = profileLevels.itemAt(i);
     98                     if (profileLevel.mProfile == XA_VIDEOPROFILE_AVC_BASELINE) {
     99                         // either skip past this item and don't change vector size
    100                         ++i;
    101                     } else {
    102                         // or remove this item, decrement the vector size,
    103                         // and next time through the loop check a different item at same index
    104                         profileLevels.removeAt(i);
    105                         --size;
    106                     }
    107                 }
    108             }
    109 #endif
    110             if ((VideoDecoderNbProfLevel[m] = profileLevels.size()) > 0) {
    111                 NbSupportedDecoderTypes++;
    112             }
    113 
    114             // only consider first codec implementation for given decoder ID / MIME type
    115             break;
    116         }
    117     }
    118 
    119     return (NbSupportedDecoderTypes > 0);
    120 }
    121 
    122 
    123 void android_videoCodec_deinit() {
    124     SL_LOGV("android_videoCodec_deinit()");
    125     // not needed
    126     // memset(VideoDecoderNbProfLevel, 0, sizeof(VideoDecoderNbProfLevel));
    127     // NbSupportedDecoderTypes = 0;
    128 }
    129 
    130 
    131 XAuint32 android_videoCodec_getNbDecoders() {
    132     return NbSupportedDecoderTypes;
    133 }
    134 
    135 
    136 void android_videoCodec_getDecoderIds(XAuint32 nbDecoders, XAuint32 *pDecoderIds) {
    137     XAuint32 *pIds = pDecoderIds;
    138     XAuint32 nbFound = 0;
    139     for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) {
    140         if (VideoDecoderNbProfLevel[m] > 0) {
    141             *pIds = VideoDecoderIds[m];
    142             pIds++;
    143             nbFound++;
    144         }
    145         // range check: function can be called for fewer codecs than there are
    146         if (nbFound == nbDecoders) {
    147             break;
    148         }
    149     }
    150 }
    151 
    152 
    153 SLresult android_videoCodec_getProfileLevelCombinationNb(XAuint32 decoderId, XAuint32 *pNb)
    154 {
    155     // translate a decoder ID to an index in the codec table
    156     size_t decoderIndex = 0;
    157     while (decoderIndex < kNbVideoMimeTypes) {
    158         if (decoderId == VideoDecoderIds[decoderIndex]) {
    159             *pNb = VideoDecoderNbProfLevel[decoderIndex];
    160             return XA_RESULT_SUCCESS;
    161         }
    162         decoderIndex++;
    163     }
    164 
    165     // spec doesn't allow a decoder to report zero profile/level combinations
    166     *pNb = 0;
    167     return XA_RESULT_PARAMETER_INVALID;
    168 }
    169 
    170 
    171 SLresult android_videoCodec_getProfileLevelCombination(XAuint32 decoderId, XAuint32 plIndex,
    172         XAVideoCodecDescriptor *pDescr)
    173 {
    174     // translate a decoder ID to an index in the codec table
    175     size_t decoderIndex = 0;
    176     while (decoderIndex < kNbVideoMimeTypes) {
    177         if (decoderId == VideoDecoderIds[decoderIndex]) {
    178             // We only look at the first codec implementation for a given decoder ID / MIME type.
    179             // OpenMAX AL doesn't let you expose the capabilities of multiple codec implementations.
    180             if (!(plIndex < VideoDecoderCapabilities[decoderIndex].mProfileLevels.size()))
    181             {
    182                 // asking for invalid profile/level
    183                 return XA_RESULT_PARAMETER_INVALID;
    184             }
    185             //     set the fields we know about
    186             pDescr->codecId = decoderId;
    187             pDescr->profileSetting = convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex].
    188                     mProfileLevels.itemAt(plIndex).mProfile);
    189             pDescr->levelSetting = convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex].
    190                     mProfileLevels.itemAt(plIndex).mLevel);
    191             //     initialize the fields we don't know about
    192             pDescr->maxWidth = 0;
    193             pDescr->maxHeight = 0;
    194             pDescr->maxFrameRate = 0;
    195             pDescr->maxBitRate = 0;
    196             pDescr->rateControlSupported = 0;
    197             break;
    198         }
    199         decoderIndex++;
    200     }
    201     return (decoderIndex < kNbVideoMimeTypes) ? XA_RESULT_SUCCESS : XA_RESULT_PARAMETER_INVALID;
    202 }
    203 
    204 } // namespace android
    205