VideoCodec_to_android.cpp revision 6e7e174807fc639c49125ced8962aa369370fbf0
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 <binder/IServiceManager.h>
20#include <utils/RefBase.h>
21#include <media/IMediaPlayerService.h>
22#include <media/stagefright/OMXClient.h>
23#include <media/stagefright/OMXCodec.h>
24#include <media/IOMX.h>
25#include <media/stagefright/MediaDefs.h>
26
27
28namespace android {
29
30static sp<IOMX> omx;
31
32// listed in same order as VideoCodecIds[] in file "../devices.c" with ANDROID defined
33static const char *kVideoMimeTypes[] = {
34        MEDIA_MIMETYPE_VIDEO_MPEG2,
35        MEDIA_MIMETYPE_VIDEO_H263,
36        MEDIA_MIMETYPE_VIDEO_MPEG4,
37        MEDIA_MIMETYPE_VIDEO_AVC,
38        MEDIA_MIMETYPE_VIDEO_VPX
39};
40static const size_t kNbVideoMimeTypes = sizeof(kVideoMimeTypes) / sizeof(kVideoMimeTypes[0]);
41
42// codec capabilities in the following arrays maps to the mime types defined in kVideoMimeTypes
43static Vector<CodecCapabilities> VideoDecoderCapabilities[kNbVideoMimeTypes];
44static XAuint32 VideoDecoderNbProfLevel[kNbVideoMimeTypes];
45
46static XAuint32 NbSupportedDecoderTypes = 0;
47
48
49XAuint32 convertOpenMaxIlToAl(OMX_U32 ilVideoProfileOrLevel) {
50    // For video codec profiles and levels, the number of trailing zeroes in OpenMAX IL
51    // are equal to the matching OpenMAX AL constant value plus 1, for example:
52    //    XA_VIDEOPROFILE_H263_BACKWARDCOMPATIBLE ((XAuint32) 0x00000003)
53    //        matches
54    //    OMX_VIDEO_H263ProfileBackwardCompatible  = 0x04
55    return (XAuint32) (__builtin_ctz(ilVideoProfileOrLevel) + 1);
56}
57
58
59bool android_videoCodec_expose() {
60    SL_LOGV("android_videoCodec_expose()");
61
62    sp<IServiceManager> sm = defaultServiceManager();
63    sp<IBinder> binder = sm->getService(String16("media.player"));
64    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
65
66    if (service.get() == NULL) {
67        LOGE("android_videoCodec_expose() couldn't access media player service");
68        return false;
69    }
70
71    omx = service->getOMX();
72    if (omx.get() == NULL) {
73        LOGE("android_videoCodec_expose() couldn't access OMX interface");
74        return false;
75    }
76
77    // used to check whether no codecs were found, which is a sign of failure
78    NbSupportedDecoderTypes = 0;
79    for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) {
80        if (OK == QueryCodecs(omx, kVideoMimeTypes[m], true /* queryDecoders */,
81                true /* hwCodecOnly */, &VideoDecoderCapabilities[m])) {
82            if (!VideoDecoderCapabilities[m].empty()) {
83                NbSupportedDecoderTypes++;
84            }
85            // for each decoder of the given decoder ID, verify it is a hardware decoder
86            for (size_t c = 0 ; c < VideoDecoderCapabilities[m].size() ; c++) {
87                VideoDecoderNbProfLevel[c] = 0;
88                const String8& compName =
89                        VideoDecoderCapabilities[m].itemAt(c).mComponentName;
90                // get the number of profiles and levels for this decoder
91                VideoDecoderNbProfLevel[m] =
92                        VideoDecoderCapabilities[m].itemAt(c).mProfileLevels.size();
93                if (VideoDecoderNbProfLevel[m] != 0) {
94                    SL_LOGV("codec %d nb prof/level=%d", m, VideoDecoderNbProfLevel[m]);
95                    break;
96                }
97            }
98        }
99    }
100
101    return (NbSupportedDecoderTypes > 0);
102}
103
104
105void android_videoCodec_deinit() {
106    SL_LOGV("android_videoCodec_deinit()");
107    LOGE("android_videoCodec_deinit()");
108    for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) {
109        VideoDecoderCapabilities[m].clear();
110    }
111}
112
113
114XAuint32 android_videoCodec_getNbDecoders() {
115    return NbSupportedDecoderTypes;
116}
117
118
119void android_videoCodec_getDecoderIds(XAuint32 nbDecoders, XAuint32 *pDecoderIds) {
120    XAuint32 *pIds = pDecoderIds;
121    XAuint32 nbFound = 0;
122    for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) {
123        if (!VideoDecoderCapabilities[m].empty()) {
124            *pIds = VideoDecoderIds[m];
125            pIds++;
126            nbFound++;
127        }
128        // range check: function can be called for fewer codecs than there are
129        if (nbFound == nbDecoders) {
130            break;
131        }
132    }
133}
134
135
136SLresult android_videoCodec_getProfileLevelCombinationNb(XAuint32 decoderId, XAuint32 *pNb)
137{
138    // translate a decoder ID to an index in the codec table
139    size_t decoderIndex = 0;
140    *pNb = 0;
141    while (decoderIndex < kNbVideoMimeTypes) {
142        if (decoderId == VideoDecoderIds[decoderIndex]) {
143            *pNb = VideoDecoderNbProfLevel[decoderIndex];
144        }
145        decoderIndex++;
146    }
147
148    return *pNb > 0 ? XA_RESULT_SUCCESS : XA_RESULT_PARAMETER_INVALID;
149}
150
151
152SLresult android_videoCodec_getProfileLevelCombination(XAuint32 decoderId, XAuint32 plIndex,
153        XAVideoCodecDescriptor *pDescr)
154{
155    // translate a decoder ID to an index in the codec table
156    size_t decoderIndex = 0;
157    while (decoderIndex < kNbVideoMimeTypes) {
158        if (decoderId == VideoDecoderIds[decoderIndex]) {
159            if (!(plIndex < VideoDecoderCapabilities[decoderIndex].itemAt(0).mProfileLevels.size()))
160            {
161                // asking for invalid profile/level
162                return XA_RESULT_PARAMETER_INVALID;
163            }
164            // we only look at the first codec, OpenMAX AL doesn't let you expose the capabilities
165            //  of multiple codecs
166            pDescr->codecId = decoderId;
167            pDescr->profileSetting = convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex].
168                    itemAt(0).mProfileLevels.itemAt(plIndex).mProfile);
169            pDescr->levelSetting =  convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex].
170                    itemAt(0).mProfileLevels.itemAt(plIndex).mLevel);
171            break;
172        }
173        decoderIndex++;
174    }
175    return (decoderIndex < kNbVideoMimeTypes) ? XA_RESULT_SUCCESS : XA_RESULT_PARAMETER_INVALID;
176}
177
178} // namespace android
179