IMediaMetadataRetriever.cpp revision b7056fc8525e0515c6f46676e3307088f8b64cdc
1/* 2** 3** Copyright (C) 2008 The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#include <stdint.h> 19#include <sys/types.h> 20#include <binder/Parcel.h> 21#include <SkBitmap.h> 22#include <media/IMediaMetadataRetriever.h> 23 24namespace android { 25 26enum { 27 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, 28 SET_DATA_SOURCE_URL, 29 SET_DATA_SOURCE_FD, 30 SET_MODE, 31 GET_MODE, 32 CAPTURE_FRAME, 33 EXTARCT_ALBUM_ART, 34 EXTRACT_METADATA, 35}; 36 37class BpMediaMetadataRetriever: public BpInterface<IMediaMetadataRetriever> 38{ 39public: 40 BpMediaMetadataRetriever(const sp<IBinder>& impl) 41 : BpInterface<IMediaMetadataRetriever>(impl) 42 { 43 } 44 45 // disconnect from media metadata retriever service 46 void disconnect() 47 { 48 Parcel data, reply; 49 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); 50 remote()->transact(DISCONNECT, data, &reply); 51 } 52 53 status_t setDataSource(const char* srcUrl) 54 { 55 Parcel data, reply; 56 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); 57 data.writeCString(srcUrl); 58 remote()->transact(SET_DATA_SOURCE_URL, data, &reply); 59 return reply.readInt32(); 60 } 61 62 status_t setDataSource(int fd, int64_t offset, int64_t length) 63 { 64 Parcel data, reply; 65 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); 66 data.writeFileDescriptor(fd); 67 data.writeInt64(offset); 68 data.writeInt64(length); 69 remote()->transact(SET_DATA_SOURCE_FD, data, &reply); 70 return reply.readInt32(); 71 } 72 73 status_t setMode(int mode) 74 { 75 Parcel data, reply; 76 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); 77 data.writeInt32(mode); 78 remote()->transact(SET_MODE, data, &reply); 79 return reply.readInt32(); 80 } 81 82 status_t getMode(int* mode) const 83 { 84 Parcel data, reply; 85 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); 86 remote()->transact(GET_MODE, data, &reply); 87 *mode = reply.readInt32(); 88 return reply.readInt32(); 89 } 90 91 sp<IMemory> captureFrame() 92 { 93 Parcel data, reply; 94 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); 95 remote()->transact(CAPTURE_FRAME, data, &reply); 96 status_t ret = reply.readInt32(); 97 if (ret != NO_ERROR) { 98 return NULL; 99 } 100 return interface_cast<IMemory>(reply.readStrongBinder()); 101 } 102 103 sp<IMemory> extractAlbumArt() 104 { 105 Parcel data, reply; 106 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); 107 remote()->transact(EXTARCT_ALBUM_ART, data, &reply); 108 status_t ret = reply.readInt32(); 109 if (ret != NO_ERROR) { 110 return NULL; 111 } 112 return interface_cast<IMemory>(reply.readStrongBinder()); 113 } 114 115 const char* extractMetadata(int keyCode) 116 { 117 Parcel data, reply; 118 data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); 119 data.writeInt32(keyCode); 120 remote()->transact(EXTRACT_METADATA, data, &reply); 121 status_t ret = reply.readInt32(); 122 if (ret != NO_ERROR) { 123 return NULL; 124 } 125 return reply.readCString(); 126 } 127}; 128 129IMPLEMENT_META_INTERFACE(MediaMetadataRetriever, "android.hardware.IMediaMetadataRetriever"); 130 131// ---------------------------------------------------------------------- 132 133status_t BnMediaMetadataRetriever::onTransact( 134 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 135{ 136 switch (code) { 137 case DISCONNECT: { 138 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 139 disconnect(); 140 return NO_ERROR; 141 } break; 142 case SET_DATA_SOURCE_URL: { 143 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 144 const char* srcUrl = data.readCString(); 145 reply->writeInt32(setDataSource(srcUrl)); 146 return NO_ERROR; 147 } break; 148 case SET_DATA_SOURCE_FD: { 149 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 150 int fd = dup(data.readFileDescriptor()); 151 int64_t offset = data.readInt64(); 152 int64_t length = data.readInt64(); 153 reply->writeInt32(setDataSource(fd, offset, length)); 154 return NO_ERROR; 155 } break; 156 case SET_MODE: { 157 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 158 int mode = data.readInt32(); 159 reply->writeInt32(setMode(mode)); 160 return NO_ERROR; 161 } break; 162 case GET_MODE: { 163 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 164 int mode; 165 status_t status = getMode(&mode); 166 reply->writeInt32(mode); 167 reply->writeInt32(status); 168 return NO_ERROR; 169 } break; 170 case CAPTURE_FRAME: { 171 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 172 sp<IMemory> bitmap = captureFrame(); 173 if (bitmap != 0) { // Don't send NULL across the binder interface 174 reply->writeInt32(NO_ERROR); 175 reply->writeStrongBinder(bitmap->asBinder()); 176 } else { 177 reply->writeInt32(UNKNOWN_ERROR); 178 } 179 return NO_ERROR; 180 } break; 181 case EXTARCT_ALBUM_ART: { 182 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 183 sp<IMemory> albumArt = extractAlbumArt(); 184 if (albumArt != 0) { // Don't send NULL across the binder interface 185 reply->writeInt32(NO_ERROR); 186 reply->writeStrongBinder(albumArt->asBinder()); 187 } else { 188 reply->writeInt32(UNKNOWN_ERROR); 189 } 190 return NO_ERROR; 191 } break; 192 case EXTRACT_METADATA: { 193 CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); 194 int keyCode = data.readInt32(); 195 const char* value = extractMetadata(keyCode); 196 if (value != NULL) { // Don't send NULL across the binder interface 197 reply->writeInt32(NO_ERROR); 198 reply->writeCString(value); 199 } else { 200 reply->writeInt32(UNKNOWN_ERROR); 201 } 202 return NO_ERROR; 203 } break; 204 default: 205 return BBinder::onTransact(code, data, reply, flags); 206 } 207} 208 209// ---------------------------------------------------------------------------- 210 211}; // namespace android 212 213