blob: bf7c5cae64f34abf06e9f00db9e655f02718d026 [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,
33 FIND_CODEC_BY_TYPE,
34 FIND_CODEC_BY_NAME,
35};
36
37class BpMediaCodecList: public BpInterface<IMediaCodecList>
38{
39public:
40 BpMediaCodecList(const sp<IBinder>& impl)
41 : BpInterface<IMediaCodecList>(impl)
42 {
43 }
44
45 virtual size_t countCodecs() const
46 {
47 Parcel data, reply;
48 data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
49 remote()->transact(COUNT_CODECS, data, &reply);
50 return static_cast<size_t>(reply.readInt32());
51 }
52
53 virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const
54 {
55 Parcel data, reply;
56 data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
57 data.writeInt32(index);
58 remote()->transact(GET_CODEC_INFO, data, &reply);
59 status_t err = reply.readInt32();
60 if (err == OK) {
61 return MediaCodecInfo::FromParcel(reply);
62 } else {
63 return NULL;
64 }
65 }
66
67 virtual ssize_t findCodecByType(
68 const char *type, bool encoder, size_t startIndex = 0) const
69 {
70 if (startIndex > INT32_MAX) {
71 return NAME_NOT_FOUND;
72 }
73
74 Parcel data, reply;
75 data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
76 data.writeCString(type);
77 data.writeInt32(encoder);
78 data.writeInt32(startIndex);
79 remote()->transact(FIND_CODEC_BY_TYPE, data, &reply);
80 return static_cast<ssize_t>(reply.readInt32());
81 }
82
83 virtual ssize_t findCodecByName(const char *name) const
84 {
85 Parcel data, reply;
86 data.writeInterfaceToken(IMediaCodecList::getInterfaceDescriptor());
87 data.writeCString(name);
88 remote()->transact(FIND_CODEC_BY_NAME, data, &reply);
89 return static_cast<ssize_t>(reply.readInt32());
90 }
91};
92
93IMPLEMENT_META_INTERFACE(MediaCodecList, "android.media.IMediaCodecList");
94
95// ----------------------------------------------------------------------
96
97status_t BnMediaCodecList::onTransact(
98 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
99{
100 switch (code) {
101 case COUNT_CODECS:
102 {
103 CHECK_INTERFACE(IMediaCodecList, data, reply);
104 size_t count = countCodecs();
105 if (count > INT32_MAX) {
106 count = INT32_MAX;
107 }
108 reply->writeInt32(count);
109 return NO_ERROR;
110 }
111 break;
112
113 case GET_CODEC_INFO:
114 {
115 CHECK_INTERFACE(IMediaCodecList, data, reply);
116 size_t index = static_cast<size_t>(data.readInt32());
117 const sp<MediaCodecInfo> info = getCodecInfo(index);
118 if (info != NULL) {
119 reply->writeInt32(OK);
120 info->writeToParcel(reply);
121 } else {
122 reply->writeInt32(-ERANGE);
123 }
124 return NO_ERROR;
125 }
126 break;
127
128 case FIND_CODEC_BY_TYPE:
129 {
130 CHECK_INTERFACE(IMediaCodecList, data, reply);
131 const char *type = data.readCString();
132 bool isEncoder = static_cast<bool>(data.readInt32());
133 size_t startIndex = static_cast<size_t>(data.readInt32());
134 ssize_t index = findCodecByType(type, isEncoder, startIndex);
135 if (index > INT32_MAX || index < 0) {
136 index = NAME_NOT_FOUND;
137 }
138 reply->writeInt32(index);
139 return NO_ERROR;
140 }
141 break;
142
143 case FIND_CODEC_BY_NAME:
144 {
145 CHECK_INTERFACE(IMediaCodecList, data, reply);
146 const char *name = data.readCString();
147 ssize_t index = findCodecByName(name);
148 if (index > INT32_MAX || index < 0) {
149 index = NAME_NOT_FOUND;
150 }
151 reply->writeInt32(index);
152 return NO_ERROR;
153 }
154 break;
155
156 default:
157 return BBinder::onTransact(code, data, reply, flags);
158 }
159}
160
161// ----------------------------------------------------------------------------
162
163}; // namespace android