1/* 2 * Copyright (C) 2010 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//#define LOG_NDEBUG 0 18#define LOG_TAG "IStreamSource" 19#include <utils/Log.h> 20 21#include <media/IStreamSource.h> 22#include <media/stagefright/foundation/AMessage.h> 23 24#include <binder/IMemory.h> 25#include <binder/Parcel.h> 26 27namespace android { 28 29// static 30const char *const IStreamListener::kKeyResumeAtPTS = "resume-at-PTS"; 31 32// static 33const char *const IStreamListener::kKeyDiscontinuityMask = "discontinuity-mask"; 34 35// static 36const char *const IStreamListener::kKeyMediaTimeUs = "media-time-us"; 37 38// static 39const char *const IStreamListener::kKeyRecentMediaTimeUs = "recent-media-time-us"; 40 41enum { 42 // IStreamSource 43 SET_LISTENER = IBinder::FIRST_CALL_TRANSACTION, 44 SET_BUFFERS, 45 ON_BUFFER_AVAILABLE, 46 FLAGS, 47 48 // IStreamListener 49 QUEUE_BUFFER, 50 ISSUE_COMMAND, 51}; 52 53struct BpStreamSource : public BpInterface<IStreamSource> { 54 BpStreamSource(const sp<IBinder> &impl) 55 : BpInterface<IStreamSource>(impl) { 56 } 57 58 virtual void setListener(const sp<IStreamListener> &listener) { 59 Parcel data, reply; 60 data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); 61 data.writeStrongBinder(IInterface::asBinder(listener)); 62 remote()->transact(SET_LISTENER, data, &reply); 63 } 64 65 virtual void setBuffers(const Vector<sp<IMemory> > &buffers) { 66 Parcel data, reply; 67 data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); 68 data.writeInt64(static_cast<int64_t>(buffers.size())); 69 for (size_t i = 0; i < buffers.size(); ++i) { 70 data.writeStrongBinder(IInterface::asBinder(buffers.itemAt(i))); 71 } 72 remote()->transact(SET_BUFFERS, data, &reply); 73 } 74 75 virtual void onBufferAvailable(size_t index) { 76 Parcel data, reply; 77 data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); 78 data.writeInt64(static_cast<int64_t>(index)); 79 remote()->transact( 80 ON_BUFFER_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY); 81 } 82 83 virtual uint32_t flags() const { 84 Parcel data, reply; 85 data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); 86 remote()->transact(FLAGS, data, &reply); 87 88 return reply.readInt32(); 89 } 90}; 91 92IMPLEMENT_META_INTERFACE(StreamSource, "android.hardware.IStreamSource"); 93 94status_t BnStreamSource::onTransact( 95 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 96 switch (code) { 97 case SET_LISTENER: 98 { 99 CHECK_INTERFACE(IStreamSource, data, reply); 100 setListener( 101 interface_cast<IStreamListener>(data.readStrongBinder())); 102 break; 103 } 104 105 case SET_BUFFERS: 106 { 107 CHECK_INTERFACE(IStreamSource, data, reply); 108 size_t n = static_cast<size_t>(data.readInt64()); 109 Vector<sp<IMemory> > buffers; 110 for (size_t i = 0; i < n; ++i) { 111 sp<IMemory> mem = 112 interface_cast<IMemory>(data.readStrongBinder()); 113 114 buffers.push(mem); 115 } 116 setBuffers(buffers); 117 break; 118 } 119 120 case ON_BUFFER_AVAILABLE: 121 { 122 CHECK_INTERFACE(IStreamSource, data, reply); 123 onBufferAvailable(static_cast<size_t>(data.readInt64())); 124 break; 125 } 126 127 case FLAGS: 128 { 129 CHECK_INTERFACE(IStreamSource, data, reply); 130 reply->writeInt32(this->flags()); 131 break; 132 } 133 134 default: 135 return BBinder::onTransact(code, data, reply, flags); 136 } 137 138 return OK; 139} 140 141//////////////////////////////////////////////////////////////////////////////// 142 143struct BpStreamListener : public BpInterface<IStreamListener> { 144 BpStreamListener(const sp<IBinder> &impl) 145 : BpInterface<IStreamListener>(impl) { 146 } 147 148 virtual void queueBuffer(size_t index, size_t size) { 149 Parcel data, reply; 150 data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor()); 151 data.writeInt64(static_cast<int64_t>(index)); 152 data.writeInt64(static_cast<int64_t>(size)); 153 154 remote()->transact(QUEUE_BUFFER, data, &reply, IBinder::FLAG_ONEWAY); 155 } 156 157 virtual void issueCommand( 158 Command cmd, bool synchronous, const sp<AMessage> &msg) { 159 Parcel data, reply; 160 data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor()); 161 data.writeInt32(static_cast<int32_t>(cmd)); 162 data.writeInt32(static_cast<int32_t>(synchronous)); 163 164 if (msg != NULL) { 165 data.writeInt32(1); 166 msg->writeToParcel(&data); 167 } else { 168 data.writeInt32(0); 169 } 170 171 remote()->transact(ISSUE_COMMAND, data, &reply, IBinder::FLAG_ONEWAY); 172 } 173}; 174 175IMPLEMENT_META_INTERFACE(StreamListener, "android.hardware.IStreamListener"); 176 177status_t BnStreamListener::onTransact( 178 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 179 switch (code) { 180 case QUEUE_BUFFER: 181 { 182 CHECK_INTERFACE(IStreamListener, data, reply); 183 size_t index = static_cast<size_t>(data.readInt64()); 184 size_t size = static_cast<size_t>(data.readInt64()); 185 186 queueBuffer(index, size); 187 break; 188 } 189 190 case ISSUE_COMMAND: 191 { 192 CHECK_INTERFACE(IStreamListener, data, reply); 193 Command cmd = static_cast<Command>(data.readInt32()); 194 195 bool synchronous = static_cast<bool>(data.readInt32()); 196 197 sp<AMessage> msg; 198 199 if (data.readInt32()) { 200 msg = AMessage::FromParcel(data); 201 } 202 203 issueCommand(cmd, synchronous, msg); 204 break; 205 } 206 207 default: 208 return BBinder::onTransact(code, data, reply, flags); 209 } 210 211 return OK; 212} 213 214} // namespace android 215