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