• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
27 namespace android {
28 
29 // static
30 const char *const IStreamListener::kKeyResumeAtPTS = "resume-at-PTS";
31 
32 // static
33 const char *const IStreamListener::kKeyFormatChange = "format-change";
34 
35 enum {
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 
46 struct BpStreamSource : public BpInterface<IStreamSource> {
BpStreamSourceandroid::BpStreamSource47     BpStreamSource(const sp<IBinder> &impl)
48         : BpInterface<IStreamSource>(impl) {
49     }
50 
setListenerandroid::BpStreamSource51     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 
setBuffersandroid::BpStreamSource58     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 
onBufferAvailableandroid::BpStreamSource68     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 
77 IMPLEMENT_META_INTERFACE(StreamSource, "android.hardware.IStreamSource");
78 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)79 status_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 
121 struct BpStreamListener : public BpInterface<IStreamListener> {
BpStreamListenerandroid::BpStreamListener122     BpStreamListener(const sp<IBinder> &impl)
123         : BpInterface<IStreamListener>(impl) {
124     }
125 
queueBufferandroid::BpStreamListener126     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 
issueCommandandroid::BpStreamListener135     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 
153 IMPLEMENT_META_INTERFACE(StreamListener, "android.hardware.IStreamListener");
154 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)155 status_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