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/IMediaPlayerService.h>
     20 #include <media/stagefright/OMXClient.h>
     21 #include <media/stagefright/OMXCodec.h>
     22 #include <media/IOMX.h>
     23 #include <media/stagefright/MediaDefs.h>
     24 
     25 
     26 namespace android {
     27 
     28 static sp<IOMX> omx;
     29 
     30 // listed in same order as VideoCodecIds[] in file "../devices.c" with ANDROID defined
     31 static const char *kVideoMimeTypes[] = {
     32         MEDIA_MIMETYPE_VIDEO_MPEG2,
     33         MEDIA_MIMETYPE_VIDEO_H263,
     34         MEDIA_MIMETYPE_VIDEO_MPEG4,
     35         MEDIA_MIMETYPE_VIDEO_AVC,
     36         MEDIA_MIMETYPE_VIDEO_VPX
     37 };
     38 static const size_t kNbVideoMimeTypes = sizeof(kVideoMimeTypes) / sizeof(kVideoMimeTypes[0]);
     39 
     40 // codec capabilities in the following arrays maps to the mime types defined in kVideoMimeTypes
     41 static Vector<CodecCapabilities> VideoDecoderCapabilities[kNbVideoMimeTypes];
     42 static XAuint32 VideoDecoderNbProfLevel[kNbVideoMimeTypes];
     43 
     44 static XAuint32 NbSupportedDecoderTypes = 0;
     45 
     46 
     47 XAuint32 convertOpenMaxIlToAl(OMX_U32 ilVideoProfileOrLevel) {
     48     // For video codec profiles and levels, the number of trailing zeroes in OpenMAX IL
     49     // are equal to the matching OpenMAX AL constant value plus 1, for example:
     50     //    XA_VIDEOPROFILE_H263_BACKWARDCOMPATIBLE ((XAuint32) 0x00000003)
     51     //        matches
     52     //    OMX_VIDEO_H263ProfileBackwardCompatible  = 0x04
     53     return (XAuint32) (__builtin_ctz(ilVideoProfileOrLevel) + 1);
     54 }
     55 
     56 
     57 bool android_videoCodec_expose() {
     58     SL_LOGV("android_videoCodec_expose()");
     59 
     60     sp<IMediaPlayerService> service(IMediaDeathNotifier::getMediaPlayerService());
     61     if (service == NULL) {
     62         // no need to SL_LOGE; getMediaPlayerService already will have done so
     63         return false;
     64     }
     65 
     66     omx = service->getOMX();
     67     if (omx.get() == NULL) {
     68         LOGE("android_videoCodec_expose() couldn't access OMX interface");
     69         return false;
     70     }
     71 
     72     // used to check whether no codecs were found, which is a sign of failure
     73     NbSupportedDecoderTypes = 0;
     74     for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) {
     75         if (OK == QueryCodecs(omx, kVideoMimeTypes[m], true /* queryDecoders */,
     76                 true /* hwCodecOnly */, &VideoDecoderCapabilities[m])) {
     77             if (!VideoDecoderCapabilities[m].empty()) {
     78                 NbSupportedDecoderTypes++;
     79             }
     80             // for each decoder of the given decoder ID, verify it is a hardware decoder
     81             for (size_t c = 0 ; c < VideoDecoderCapabilities[m].size() ; c++) {
     82                 VideoDecoderNbProfLevel[c] = 0;
     83                 const String8& compName =
     84                         VideoDecoderCapabilities[m].itemAt(c).mComponentName;
     85                 // get the number of profiles and levels for this decoder
     86                 VideoDecoderNbProfLevel[m] =
     87                         VideoDecoderCapabilities[m].itemAt(c).mProfileLevels.size();
     88                 if (VideoDecoderNbProfLevel[m] != 0) {
     89                     SL_LOGV("codec %d nb prof/level=%d", m, VideoDecoderNbProfLevel[m]);
     90                     break;
     91                 }
     92             }
     93         }
     94     }
     95 
     96     return (NbSupportedDecoderTypes > 0);
     97 }
     98 
     99 
    100 void android_videoCodec_deinit() {
    101     SL_LOGV("android_videoCodec_deinit()");
    102     for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) {
    103         VideoDecoderCapabilities[m].clear();
    104     }
    105 }
    106 
    107 
    108 XAuint32 android_videoCodec_getNbDecoders() {
    109     return NbSupportedDecoderTypes;
    110 }
    111 
    112 
    113 void android_videoCodec_getDecoderIds(XAuint32 nbDecoders, XAuint32 *pDecoderIds) {
    114     XAuint32 *pIds = pDecoderIds;
    115     XAuint32 nbFound = 0;
    116     for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) {
    117         if (!VideoDecoderCapabilities[m].empty()) {
    118             *pIds = VideoDecoderIds[m];
    119             pIds++;
    120             nbFound++;
    121         }
    122         // range check: function can be called for fewer codecs than there are
    123         if (nbFound == nbDecoders) {
    124             break;
    125         }
    126     }
    127 }
    128 
    129 
    130 SLresult android_videoCodec_getProfileLevelCombinationNb(XAuint32 decoderId, XAuint32 *pNb)
    131 {
    132     // translate a decoder ID to an index in the codec table
    133     size_t decoderIndex = 0;
    134     *pNb = 0;
    135     while (decoderIndex < kNbVideoMimeTypes) {
    136         if (decoderId == VideoDecoderIds[decoderIndex]) {
    137             *pNb = VideoDecoderNbProfLevel[decoderIndex];
    138             break;
    139         }
    140         decoderIndex++;
    141     }
    142 
    143     return XA_RESULT_SUCCESS;
    144 }
    145 
    146 
    147 SLresult android_videoCodec_getProfileLevelCombination(XAuint32 decoderId, XAuint32 plIndex,
    148         XAVideoCodecDescriptor *pDescr)
    149 {
    150     // translate a decoder ID to an index in the codec table
    151     size_t decoderIndex = 0;
    152     while (decoderIndex < kNbVideoMimeTypes) {
    153         if (decoderId == VideoDecoderIds[decoderIndex]) {
    154             if (!(plIndex < VideoDecoderCapabilities[decoderIndex].itemAt(0).mProfileLevels.size()))
    155             {
    156                 // asking for invalid profile/level
    157                 return XA_RESULT_PARAMETER_INVALID;
    158             }
    159             // we only look at the first codec, OpenMAX AL doesn't let you expose the capabilities
    160             //  of multiple codecs
    161             //     set the fields we know about
    162             pDescr->codecId = decoderId;
    163             pDescr->profileSetting = convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex].
    164                     itemAt(0).mProfileLevels.itemAt(plIndex).mProfile);
    165             pDescr->levelSetting =  convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex].
    166                     itemAt(0).mProfileLevels.itemAt(plIndex).mLevel);
    167             //     initialize the fields we don't know about
    168             pDescr->maxWidth = 0;
    169             pDescr->maxHeight = 0;
    170             pDescr->maxFrameRate = 0;
    171             pDescr->maxBitRate = 0;
    172             pDescr->rateControlSupported = 0;
    173             break;
    174         }
    175         decoderIndex++;
    176     }
    177     return (decoderIndex < kNbVideoMimeTypes) ? XA_RESULT_SUCCESS : XA_RESULT_PARAMETER_INVALID;
    178 }
    179 
    180 } // namespace android
    181