VideoCodec_to_android.cpp revision 22ced1dc023dc000118e3a26517b14e9babd7c5a
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 26namespace android { 27 28// listed in same order as VideoCodecIds[] in file "../devices.c" with ANDROID defined 29static const char *kVideoMimeTypes[] = { 30 MEDIA_MIMETYPE_VIDEO_MPEG2, 31 MEDIA_MIMETYPE_VIDEO_H263, 32 MEDIA_MIMETYPE_VIDEO_MPEG4, 33 MEDIA_MIMETYPE_VIDEO_AVC, 34 MEDIA_MIMETYPE_VIDEO_VPX 35}; 36// must == kMaxVideoDecoders 37static const size_t kNbVideoMimeTypes = sizeof(kVideoMimeTypes) / sizeof(kVideoMimeTypes[0]); 38 39// codec capabilities in the following arrays maps to the mime types defined in kVideoMimeTypes 40// CodecCapabilities is from OMXCodec.h 41static Vector<CodecCapabilities> VideoDecoderCapabilities[kNbVideoMimeTypes]; 42static XAuint32 VideoDecoderNbProfLevel[kNbVideoMimeTypes]; 43 44static XAuint32 NbSupportedDecoderTypes = 0; 45 46 47XAuint32 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 57bool 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 sp<IOMX> 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 // QueryCodecs is from OMXCodec.h 76 if (OK == QueryCodecs(omx, kVideoMimeTypes[m], true /* queryDecoders */, 77 true /* hwCodecOnly */, &VideoDecoderCapabilities[m])) { 78 if (VideoDecoderCapabilities[m].empty()) { 79 VideoDecoderNbProfLevel[m] = 0; 80 } else { 81 // get the number of profiles and levels for the first codec implementation 82 // for a given decoder ID / MIME type 83 Vector<CodecProfileLevel> &profileLevels = 84 VideoDecoderCapabilities[m].editItemAt(0).mProfileLevels; 85#if 0 // Intentionally disabled example of making modifications to profile / level combinations 86 if (VideoDecoderIds[m] == XA_VIDEOCODEC_AVC) { 87 // remove non-core profile / level combinations 88 for (size_t i = 0, size = profileLevels.size(); i < size; ) { 89 CodecProfileLevel profileLevel = profileLevels.itemAt(i); 90 if (profileLevel.mProfile == XA_VIDEOPROFILE_AVC_BASELINE) { 91 // either skip past this item and don't change vector size 92 ++i; 93 } else { 94 // or remove this item, decrement the vector size, 95 // and next time through the loop check a different item at same index 96 profileLevels.removeAt(i); 97 --size; 98 } 99 } 100 } 101#endif 102 if ((VideoDecoderNbProfLevel[m] = profileLevels.size()) > 0) { 103 NbSupportedDecoderTypes++; 104 } else { 105 VideoDecoderCapabilities[m].clear(); 106 } 107 } 108 } 109 } 110 111 return (NbSupportedDecoderTypes > 0); 112} 113 114 115void android_videoCodec_deinit() { 116 SL_LOGV("android_videoCodec_deinit()"); 117 for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) { 118 VideoDecoderCapabilities[m].clear(); 119 } 120 // not needed 121 // memset(VideoDecoderNbProfLevel, 0, sizeof(VideoDecoderNbProfLevel)); 122 // NbSupportedDecoderTypes = 0; 123} 124 125 126XAuint32 android_videoCodec_getNbDecoders() { 127 return NbSupportedDecoderTypes; 128} 129 130 131void android_videoCodec_getDecoderIds(XAuint32 nbDecoders, XAuint32 *pDecoderIds) { 132 XAuint32 *pIds = pDecoderIds; 133 XAuint32 nbFound = 0; 134 for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) { 135 if (!VideoDecoderCapabilities[m].empty()) { 136 *pIds = VideoDecoderIds[m]; 137 pIds++; 138 nbFound++; 139 } 140 // range check: function can be called for fewer codecs than there are 141 if (nbFound == nbDecoders) { 142 break; 143 } 144 } 145} 146 147 148SLresult android_videoCodec_getProfileLevelCombinationNb(XAuint32 decoderId, XAuint32 *pNb) 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 *pNb = VideoDecoderNbProfLevel[decoderIndex]; 155 return XA_RESULT_SUCCESS; 156 } 157 decoderIndex++; 158 } 159 160 // spec doesn't allow a decoder to report zero profile/level combinations 161 *pNb = 0; 162 return XA_RESULT_PARAMETER_INVALID; 163} 164 165 166SLresult android_videoCodec_getProfileLevelCombination(XAuint32 decoderId, XAuint32 plIndex, 167 XAVideoCodecDescriptor *pDescr) 168{ 169 // translate a decoder ID to an index in the codec table 170 size_t decoderIndex = 0; 171 while (decoderIndex < kNbVideoMimeTypes) { 172 if (decoderId == VideoDecoderIds[decoderIndex]) { 173 // We only look at the first codec implementation for a given decoder ID / MIME type. 174 // OpenMAX AL doesn't let you expose the capabilities of multiple codec implementations. 175 if (!(plIndex < VideoDecoderCapabilities[decoderIndex].itemAt(0).mProfileLevels.size())) 176 { 177 // asking for invalid profile/level 178 return XA_RESULT_PARAMETER_INVALID; 179 } 180 // set the fields we know about 181 pDescr->codecId = decoderId; 182 pDescr->profileSetting = convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex]. 183 itemAt(0).mProfileLevels.itemAt(plIndex).mProfile); 184 pDescr->levelSetting = convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex]. 185 itemAt(0).mProfileLevels.itemAt(plIndex).mLevel); 186 // initialize the fields we don't know about 187 pDescr->maxWidth = 0; 188 pDescr->maxHeight = 0; 189 pDescr->maxFrameRate = 0; 190 pDescr->maxBitRate = 0; 191 pDescr->rateControlSupported = 0; 192 break; 193 } 194 decoderIndex++; 195 } 196 return (decoderIndex < kNbVideoMimeTypes) ? XA_RESULT_SUCCESS : XA_RESULT_PARAMETER_INVALID; 197} 198 199} // namespace android 200