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 35enum { 36 // IStreamSource 37 SET_LISTENER = IBinder::FIRST_CALL_TRANSACTION, 38 SET_BUFFERS, 39 ON_BUFFER_AVAILABLE, 40 41 // IStreamListener 42 QUEUE_BUFFER, 43 ISSUE_COMMAND, 44}; 45 46struct BpStreamSource : public BpInterface<IStreamSource> { 47 BpStreamSource(const sp<IBinder> &impl) 48 : BpInterface<IStreamSource>(impl) { 49 } 50 51 virtual void setListener(const sp<IStreamListener> &listener) { 52 Parcel data, reply; 53 data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); 54 data.writeStrongBinder(listener->asBinder()); 55 remote()->transact(SET_LISTENER, data, &reply); 56 } 57 58 virtual void setBuffers(const Vector<sp<IMemory> > &buffers) { 59 Parcel data, reply; 60 data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); 61 data.writeInt32(static_cast<int32_t>(buffers.size())); 62 for (size_t i = 0; i < buffers.size(); ++i) { 63 data.writeStrongBinder(buffers.itemAt(i)->asBinder()); 64 } 65 remote()->transact(SET_BUFFERS, data, &reply); 66 } 67 68 virtual void onBufferAvailable(size_t index) { 69 Parcel data, reply; 70 data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); 71 data.writeInt32(static_cast<int32_t>(index)); 72 remote()->transact( 73 ON_BUFFER_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY); 74 } 75}; 76 77IMPLEMENT_META_INTERFACE(StreamSource, "android.hardware.IStreamSource"); 78 79status_t BnStreamSource::onTransact( 80 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 81 switch (code) { 82 case SET_LISTENER: 83 { 84 CHECK_INTERFACE(IStreamSource, data, reply); 85 setListener( 86 interface_cast<IStreamListener>(data.readStrongBinder())); 87 break; 88 } 89 90 case SET_BUFFERS: 91 { 92 CHECK_INTERFACE(IStreamSource, data, reply); 93 size_t n = static_cast<size_t>(data.readInt32()); 94 Vector<sp<IMemory> > buffers; 95 for (size_t i = 0; i < n; ++i) { 96 sp<IMemory> mem = 97 interface_cast<IMemory>(data.readStrongBinder()); 98 99 buffers.push(mem); 100 } 101 setBuffers(buffers); 102 break; 103 } 104 105 case ON_BUFFER_AVAILABLE: 106 { 107 CHECK_INTERFACE(IStreamSource, data, reply); 108 onBufferAvailable(static_cast<size_t>(data.readInt32())); 109 break; 110 } 111 112 default: 113 return BBinder::onTransact(code, data, reply, flags); 114 } 115 116 return OK; 117} 118 119//////////////////////////////////////////////////////////////////////////////// 120 121struct BpStreamListener : public BpInterface<IStreamListener> { 122 BpStreamListener(const sp<IBinder> &impl) 123 : BpInterface<IStreamListener>(impl) { 124 } 125 126 virtual void queueBuffer(size_t index, size_t size) { 127 Parcel data, reply; 128 data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor()); 129 data.writeInt32(static_cast<int32_t>(index)); 130 data.writeInt32(static_cast<int32_t>(size)); 131 132 remote()->transact(QUEUE_BUFFER, data, &reply, IBinder::FLAG_ONEWAY); 133 } 134 135 virtual void issueCommand( 136 Command cmd, bool synchronous, const sp<AMessage> &msg) { 137 Parcel data, reply; 138 data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor()); 139 data.writeInt32(static_cast<int32_t>(cmd)); 140 data.writeInt32(static_cast<int32_t>(synchronous)); 141 142 if (msg != NULL) { 143 data.writeInt32(1); 144 msg->writeToParcel(&data); 145 } else { 146 data.writeInt32(0); 147 } 148 149 remote()->transact(ISSUE_COMMAND, data, &reply, IBinder::FLAG_ONEWAY); 150 } 151}; 152 153IMPLEMENT_META_INTERFACE(StreamListener, "android.hardware.IStreamListener"); 154 155status_t BnStreamListener::onTransact( 156 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 157 switch (code) { 158 case QUEUE_BUFFER: 159 { 160 CHECK_INTERFACE(IStreamListener, data, reply); 161 size_t index = static_cast<size_t>(data.readInt32()); 162 size_t size = static_cast<size_t>(data.readInt32()); 163 164 queueBuffer(index, size); 165 break; 166 } 167 168 case ISSUE_COMMAND: 169 { 170 CHECK_INTERFACE(IStreamListener, data, reply); 171 Command cmd = static_cast<Command>(data.readInt32()); 172 173 bool synchronous = static_cast<bool>(data.readInt32()); 174 175 sp<AMessage> msg; 176 177 if (data.readInt32()) { 178 msg = AMessage::FromParcel(data); 179 } 180 181 issueCommand(cmd, synchronous, msg); 182 break; 183 } 184 185 default: 186 return BBinder::onTransact(code, data, reply, flags); 187 } 188 189 return OK; 190} 191 192} // namespace android 193