VideoCodec_to_android.cpp revision d7ecf117cfac5f2b90a0dc6c62b56dcce0715971
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    for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) {
108        VideoDecoderCapabilities[m].clear();
109    }
110}
111
112
113XAuint32 android_videoCodec_getNbDecoders() {
114    return NbSupportedDecoderTypes;
115}
116
117
118void android_videoCodec_getDecoderIds(XAuint32 nbDecoders, XAuint32 *pDecoderIds) {
119    XAuint32 *pIds = pDecoderIds;
120    XAuint32 nbFound = 0;
121    for (size_t m = 0 ; m < kNbVideoMimeTypes ; m++) {
122        if (!VideoDecoderCapabilities[m].empty()) {
123            *pIds = VideoDecoderIds[m];
124            pIds++;
125            nbFound++;
126        }
127        // range check: function can be called for fewer codecs than there are
128        if (nbFound == nbDecoders) {
129            break;
130        }
131    }
132}
133
134
135SLresult android_videoCodec_getProfileLevelCombinationNb(XAuint32 decoderId, XAuint32 *pNb)
136{
137    // translate a decoder ID to an index in the codec table
138    size_t decoderIndex = 0;
139    *pNb = 0;
140    while (decoderIndex < kNbVideoMimeTypes) {
141        if (decoderId == VideoDecoderIds[decoderIndex]) {
142            *pNb = VideoDecoderNbProfLevel[decoderIndex];
143        }
144        decoderIndex++;
145    }
146
147    return *pNb > 0 ? XA_RESULT_SUCCESS : XA_RESULT_PARAMETER_INVALID;
148}
149
150
151SLresult android_videoCodec_getProfileLevelCombination(XAuint32 decoderId, XAuint32 plIndex,
152        XAVideoCodecDescriptor *pDescr)
153{
154    // translate a decoder ID to an index in the codec table
155    size_t decoderIndex = 0;
156    while (decoderIndex < kNbVideoMimeTypes) {
157        if (decoderId == VideoDecoderIds[decoderIndex]) {
158            if (!(plIndex < VideoDecoderCapabilities[decoderIndex].itemAt(0).mProfileLevels.size()))
159            {
160                // asking for invalid profile/level
161                return XA_RESULT_PARAMETER_INVALID;
162            }
163            // we only look at the first codec, OpenMAX AL doesn't let you expose the capabilities
164            //  of multiple codecs
165            pDescr->codecId = decoderId;
166            pDescr->profileSetting = convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex].
167                    itemAt(0).mProfileLevels.itemAt(plIndex).mProfile);
168            pDescr->levelSetting =  convertOpenMaxIlToAl(VideoDecoderCapabilities[decoderIndex].
169                    itemAt(0).mProfileLevels.itemAt(plIndex).mLevel);
170            break;
171        }
172        decoderIndex++;
173    }
174    return (decoderIndex < kNbVideoMimeTypes) ? XA_RESULT_SUCCESS : XA_RESULT_PARAMETER_INVALID;
175}
176
177} // namespace android
178