1b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi/* 2b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project 3b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * 4b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 5b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * you may not use this file except in compliance with the License. 6b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * You may obtain a copy of the License at 7b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * 8b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 9b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * 10b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 11b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 12b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * See the License for the specific language governing permissions and 14b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi * limitations under the License. 15b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi */ 16b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 17b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi#include "sles_allinclusive.h" 18b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 19b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi#include <media/IMediaPlayerService.h> 20b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi#include <media/stagefright/OMXClient.h> 21b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi#include <media/stagefright/OMXCodec.h> 22b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi#include <media/IOMX.h> 23b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi#include <media/stagefright/MediaDefs.h> 24b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 25b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 26b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivinamespace android { 27b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 28b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivistatic sp<IOMX> omx; 29b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 30b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi// listed in same order as VideoCodecIds[] in file "../devices.c" with ANDROID defined 31b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivistatic const char *kVideoMimeTypes[] = { 32b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi MEDIA_MIMETYPE_VIDEO_MPEG2, 33b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi MEDIA_MIMETYPE_VIDEO_H263, 34b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi MEDIA_MIMETYPE_VIDEO_MPEG4, 35b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi MEDIA_MIMETYPE_VIDEO_AVC, 36b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi MEDIA_MIMETYPE_VIDEO_VPX 37b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi}; 38b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivistatic const size_t kNbVideoMimeTypes = sizeof(kVideoMimeTypes) / sizeof(kVideoMimeTypes[0]); 39b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 40b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi// codec capabilities in the following arrays maps to the mime types defined in kVideoMimeTypes 41b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivistatic Vector<CodecCapabilities> VideoDecoderCapabilities[kNbVideoMimeTypes]; 42b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivistatic XAuint32 VideoDecoderNbProfLevel[kNbVideoMimeTypes]; 43b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 44b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivistatic XAuint32 NbSupportedDecoderTypes = 0; 45b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 46b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 47b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel TriviXAuint32 convertOpenMaxIlToAl(OMX_U32 ilVideoProfileOrLevel) { 48b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // For video codec profiles and levels, the number of trailing zeroes in OpenMAX IL 49b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // are equal to the matching OpenMAX AL constant value plus 1, for example: 50b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // XA_VIDEOPROFILE_H263_BACKWARDCOMPATIBLE ((XAuint32) 0x00000003) 51b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // matches 52b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // OMX_VIDEO_H263ProfileBackwardCompatible = 0x04 53b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi return (XAuint32) (__builtin_ctz(ilVideoProfileOrLevel) + 1); 54b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi} 55b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 56b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 57b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivibool android_videoCodec_expose() { 58b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi SL_LOGV("android_videoCodec_expose()"); 59b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 60b0865831ca1d779902e876e15e36f4402b607c5eGlenn Kasten sp<IMediaPlayerService> service(IMediaDeathNotifier::getMediaPlayerService()); 61b0865831ca1d779902e876e15e36f4402b607c5eGlenn Kasten if (service == NULL) { 62b0865831ca1d779902e876e15e36f4402b607c5eGlenn Kasten // no need to SL_LOGE; getMediaPlayerService already will have done so 63b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi return false; 64b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 65b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 66b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi omx = service->getOMX(); 67b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi if (omx.get() == NULL) { 68b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi LOGE("android_videoCodec_expose() couldn't access OMX interface"); 69b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi return false; 70b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 71b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 72b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // used to check whether no codecs were found, which is a sign of failure 73b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi NbSupportedDecoderTypes = 0; 74b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) { 75b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi if (OK == QueryCodecs(omx, kVideoMimeTypes[m], true /* queryDecoders */, 76b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi true /* hwCodecOnly */, &VideoDecoderCapabilities[m])) { 77b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi if (!VideoDecoderCapabilities[m].empty()) { 78b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi NbSupportedDecoderTypes++; 79b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 80b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // for each decoder of the given decoder ID, verify it is a hardware decoder 81b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi for (size_t c = 0 ; c < VideoDecoderCapabilities[m].size() ; c++) { 82b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi VideoDecoderNbProfLevel[c] = 0; 83b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi const String8& compName = 84b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi VideoDecoderCapabilities[m].itemAt(c).mComponentName; 85b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // get the number of profiles and levels for this decoder 86b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi VideoDecoderNbProfLevel[m] = 87b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi VideoDecoderCapabilities[m].itemAt(c).mProfileLevels.size(); 88b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi if (VideoDecoderNbProfLevel[m] != 0) { 89b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi SL_LOGV("codec %d nb prof/level=%d", m, VideoDecoderNbProfLevel[m]); 90b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi break; 91b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 92b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 93b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 94b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 95b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 96b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi return (NbSupportedDecoderTypes > 0); 97b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi} 98b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 99b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 100b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivivoid android_videoCodec_deinit() { 101b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi SL_LOGV("android_videoCodec_deinit()"); 102b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) { 103b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi VideoDecoderCapabilities[m].clear(); 104b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 105b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi} 106b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 107b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 108b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel TriviXAuint32 android_videoCodec_getNbDecoders() { 109b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi return NbSupportedDecoderTypes; 110b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi} 111b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 112b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 113b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivivoid android_videoCodec_getDecoderIds(XAuint32 nbDecoders, XAuint32 *pDecoderIds) { 114b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi XAuint32 *pIds = pDecoderIds; 115b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi XAuint32 nbFound = 0; 116b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) { 117b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi if (!VideoDecoderCapabilities[m].empty()) { 118b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi *pIds = VideoDecoderIds[m]; 119b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi pIds++; 120b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi nbFound++; 121b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 122b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // range check: function can be called for fewer codecs than there are 123b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi if (nbFound == nbDecoders) { 124b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi break; 125b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 126b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 127b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi} 128b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 129b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 130b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel TriviSLresult android_videoCodec_getProfileLevelCombinationNb(XAuint32 decoderId, XAuint32 *pNb) 131b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi{ 132b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // translate a decoder ID to an index in the codec table 133b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi size_t decoderIndex = 0; 134b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi *pNb = 0; 135b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi while (decoderIndex < kNbVideoMimeTypes) { 136b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi if (decoderId == VideoDecoderIds[decoderIndex]) { 137b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi *pNb = VideoDecoderNbProfLevel[decoderIndex]; 13831d28405cb4429674bf5eb3a617dbb0db3e3daf7Glenn Kasten break; 139b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 140b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi decoderIndex++; 141b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 142b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 14331d28405cb4429674bf5eb3a617dbb0db3e3daf7Glenn Kasten return XA_RESULT_SUCCESS; 144b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi} 145b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 146b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 147b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel TriviSLresult android_videoCodec_getProfileLevelCombination(XAuint32 decoderId, XAuint32 plIndex, 148b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi XAVideoCodecDescriptor *pDescr) 149b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi{ 150b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // translate a decoder ID to an index in the codec table 151b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi size_t decoderIndex = 0; 152b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi while (decoderIndex < kNbVideoMimeTypes) { 153b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi if (decoderId == VideoDecoderIds[decoderIndex]) { 154b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi if (!(plIndex < VideoDecoderCapabilities[decoderIndex].itemAt(0).mProfileLevels.size())) 155b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi { 156b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // asking for invalid profile/level 157b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi return XA_RESULT_PARAMETER_INVALID; 158b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 159b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // we only look at the first codec, OpenMAX AL doesn't let you expose the capabilities 160b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi // of multiple codecs 1611b067ed548f57ee752f9913011db88d18a6eaf87Jean-Michel Trivi // set the fields we know about 162b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi pDescr->codecId = decoderId; 163b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi pDescr->profileSetting = convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex]. 164b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi itemAt(0).mProfileLevels.itemAt(plIndex).mProfile); 165b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi pDescr->levelSetting = convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex]. 166b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi itemAt(0).mProfileLevels.itemAt(plIndex).mLevel); 1671b067ed548f57ee752f9913011db88d18a6eaf87Jean-Michel Trivi // initialize the fields we don't know about 1681b067ed548f57ee752f9913011db88d18a6eaf87Jean-Michel Trivi pDescr->maxWidth = 0; 1691b067ed548f57ee752f9913011db88d18a6eaf87Jean-Michel Trivi pDescr->maxHeight = 0; 1701b067ed548f57ee752f9913011db88d18a6eaf87Jean-Michel Trivi pDescr->maxFrameRate = 0; 1711b067ed548f57ee752f9913011db88d18a6eaf87Jean-Michel Trivi pDescr->maxBitRate = 0; 1721b067ed548f57ee752f9913011db88d18a6eaf87Jean-Michel Trivi pDescr->rateControlSupported = 0; 173b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi break; 174b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 175b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi decoderIndex++; 176b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi } 177b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi return (decoderIndex < kNbVideoMimeTypes) ? XA_RESULT_SUCCESS : XA_RESULT_PARAMETER_INVALID; 178b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi} 179b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi 180b6ce251c4b009003822ddf0323c11b4a5e74eeb2Jean-Michel Trivi} // namespace android 181