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