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
convertOpenMaxIlToAl(OMX_U32 ilVideoProfileOrLevel)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
android_videoCodec_expose()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
android_videoCodec_deinit()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
android_videoCodec_getNbDecoders()108 XAuint32 android_videoCodec_getNbDecoders() {
109 return NbSupportedDecoderTypes;
110 }
111
112
android_videoCodec_getDecoderIds(XAuint32 nbDecoders,XAuint32 * pDecoderIds)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
android_videoCodec_getProfileLevelCombinationNb(XAuint32 decoderId,XAuint32 * pNb)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
android_videoCodec_getProfileLevelCombination(XAuint32 decoderId,XAuint32 plIndex,XAVideoCodecDescriptor * pDescr)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