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