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