• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
27 namespace android {
28 
29 enum {
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 
37 class BpMediaCodecList: public BpInterface<IMediaCodecList>
38 {
39 public:
BpMediaCodecList(const sp<IBinder> & impl)40     BpMediaCodecList(const sp<IBinder>& impl)
41         : BpInterface<IMediaCodecList>(impl)
42     {
43     }
44 
countCodecs() const45     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 
getCodecInfo(size_t index) const53     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 
findCodecByType(const char * type,bool encoder,size_t startIndex=0) const67     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 
findCodecByName(const char * name) const83     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 
93 IMPLEMENT_META_INTERFACE(MediaCodecList, "android.media.IMediaCodecList");
94 
95 // ----------------------------------------------------------------------
96 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)97 status_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
164