blob: 737f50c5c3bfc2e319d3ff64f7621eaa4c204a3b [file] [log] [blame]
Lajos Molnar60b1c0e2014-08-06 16:55:46 -07001/*
2 * Copyright (C) 2014, 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 <stdint.h>
18#include <sys/types.h>
19
20#include <binder/Parcel.h>
21#include <media/stagefright/MediaCodecList.h>
22#include <media/IMediaCodecList.h>
23#include <media/MediaCodecInfo.h>
24
25#include <utils/Errors.h> // for status_t
26
27namespace android {
28
29enum {
30 CREATE = IBinder::FIRST_CALL_TRANSACTION,
31 COUNT_CODECS,
32 GET_CODEC_INFO,
Ronghua Wu9e6955a2015-03-26 13:52:57 -070033 GET_GLOBAL_SETTINGS,
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070034 FIND_CODEC_BY_TYPE,
35 FIND_CODEC_BY_NAME,
36};
37
38class BpMediaCodecList: public BpInterface<IMediaCodecList>
39{
40public:
41 BpMediaCodecList(const sp<IBinder>& impl)
42 : BpInterface<IMediaCodecList>(impl)
43 {
44 }
45
46 virtual size_t countCodecs() const
47 {
48 Parcel data, reply;
49 data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
50 remote()->transact(COUNT_CODECS, data, &reply);
51 return static_cast<size_t>(reply.readInt32());
52 }
53
54 virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const
55 {
56 Parcel data, reply;
57 data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
58 data.writeInt32(index);
59 remote()->transact(GET_CODEC_INFO, data, &reply);
60 status_t err = reply.readInt32();
61 if (err == OK) {
62 return MediaCodecInfo::FromParcel(reply);
63 } else {
64 return NULL;
65 }
66 }
67
Ronghua Wu9e6955a2015-03-26 13:52:57 -070068 virtual const sp<AMessage> getGlobalSettings() const
69 {
70 Parcel data, reply;
71 data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
72 remote()->transact(GET_GLOBAL_SETTINGS, data, &reply);
73 status_t err = reply.readInt32();
74 if (err == OK) {
75 return AMessage::FromParcel(reply);
76 } else {
77 return NULL;
78 }
79 }
80
Lajos Molnar60b1c0e2014-08-06 16:55:46 -070081 virtual ssize_t findCodecByType(
82 const char *type, bool encoder, size_t startIndex = 0) const
83 {
84 if (startIndex > INT32_MAX) {
85 return NAME_NOT_FOUND;
86 }
87
88 Parcel data, reply;
89 data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
90 data.writeCString(type);
91 data.writeInt32(encoder);
92 data.writeInt32(startIndex);
93 remote()->transact(FIND_CODEC_BY_TYPE, data, &reply);
94 return static_cast<ssize_t>(reply.readInt32());
95 }
96
97 virtual ssize_t findCodecByName(const char *name) const
98 {
99 Parcel data, reply;
100 data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
101 data.writeCString(name);
102 remote()->transact(FIND_CODEC_BY_NAME, data, &reply);
103 return static_cast<ssize_t>(reply.readInt32());
104 }
105};
106
107IMPLEMENT_META_INTERFACE(MediaCodecList, "android.media.IMediaCodecList");
108
109// ----------------------------------------------------------------------
110
111status_t BnMediaCodecList::onTransact(
112 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
113{
114 switch (code) {
115 case COUNT_CODECS:
116 {
117 CHECK_INTERFACE(IMediaCodecList, data, reply);
118 size_t count = countCodecs();
119 if (count > INT32_MAX) {
120 count = INT32_MAX;
121 }
122 reply->writeInt32(count);
123 return NO_ERROR;
124 }
125 break;
126
127 case GET_CODEC_INFO:
128 {
129 CHECK_INTERFACE(IMediaCodecList, data, reply);
130 size_t index = static_cast<size_t>(data.readInt32());
131 const sp<MediaCodecInfo> info = getCodecInfo(index);
132 if (info != NULL) {
133 reply->writeInt32(OK);
134 info->writeToParcel(reply);
135 } else {
136 reply->writeInt32(-ERANGE);
137 }
138 return NO_ERROR;
139 }
140 break;
141
Ronghua Wu9e6955a2015-03-26 13:52:57 -0700142 case GET_GLOBAL_SETTINGS:
143 {
144 CHECK_INTERFACE(IMediaCodecList, data, reply);
145 const sp<AMessage> info = getGlobalSettings();
146 if (info != NULL) {
147 reply->writeInt32(OK);
148 info->writeToParcel(reply);
149 } else {
150 reply->writeInt32(-ERANGE);
151 }
152 return NO_ERROR;
153 }
154 break;
155
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700156 case FIND_CODEC_BY_TYPE:
157 {
158 CHECK_INTERFACE(IMediaCodecList, data, reply);
159 const char *type = data.readCString();
Wei Jia2afac0c2016-01-07 12:13:07 -0800160 if (type == NULL) {
161 reply->writeInt32(NAME_NOT_FOUND);
162 return NO_ERROR;
163 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700164 bool isEncoder = static_cast<bool>(data.readInt32());
165 size_t startIndex = static_cast<size_t>(data.readInt32());
166 ssize_t index = findCodecByType(type, isEncoder, startIndex);
167 if (index > INT32_MAX || index < 0) {
168 index = NAME_NOT_FOUND;
169 }
170 reply->writeInt32(index);
171 return NO_ERROR;
172 }
173 break;
174
175 case FIND_CODEC_BY_NAME:
176 {
177 CHECK_INTERFACE(IMediaCodecList, data, reply);
178 const char *name = data.readCString();
Wei Jia2afac0c2016-01-07 12:13:07 -0800179 if (name == NULL) {
180 reply->writeInt32(NAME_NOT_FOUND);
181 return NO_ERROR;
182 }
Lajos Molnar60b1c0e2014-08-06 16:55:46 -0700183 ssize_t index = findCodecByName(name);
184 if (index > INT32_MAX || index < 0) {
185 index = NAME_NOT_FOUND;
186 }
187 reply->writeInt32(index);
188 return NO_ERROR;
189 }
190 break;
191
192 default:
193 return BBinder::onTransact(code, data, reply, flags);
194 }
195}
196
197// ----------------------------------------------------------------------------
198
Glenn Kasten40bc9062015-03-20 09:09:33 -0700199} // namespace android