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