IMediaSource.cpp revision 1d5a306c0b1322168e8f9fcf81876118a355a400
1b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen/*
2b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * Copyright (C) 2009 The Android Open Source Project
3b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen *
4b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * Licensed under the Apache License, Version 2.0 (the "License");
5b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * you may not use this file except in compliance with the License.
6b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * You may obtain a copy of the License at
7b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen *
8b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen *      http://www.apache.org/licenses/LICENSE-2.0
9b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen *
10b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * Unless required by applicable law or agreed to in writing, software
11b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * distributed under the License is distributed on an "AS IS" BASIS,
12b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * See the License for the specific language governing permissions and
14b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen * limitations under the License.
15b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen */
16b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
17b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen//#define LOG_NDEBUG 0
18b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define LOG_TAG "BpMediaSource"
19b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <utils/Log.h>
20b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
21b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen#include <inttypes.h>
22b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <stdint.h>
23b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <sys/types.h>
24b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
25b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <binder/Parcel.h>
26b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <media/IMediaSource.h>
27b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <media/stagefright/MediaBuffer.h>
28e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia#include <media/stagefright/MediaBufferGroup.h>
29b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <media/stagefright/MediaSource.h>
30b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <media/stagefright/MetaData.h>
31b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
32b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissennamespace android {
33b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
34b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenenum {
35b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    START = IBinder::FIRST_CALL_TRANSACTION,
36b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    STOP,
37b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    PAUSE,
38b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    GETFORMAT,
39b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    READ,
40b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    RELEASE_BUFFER
41b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen};
42b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
43b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissenenum {
44b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    NULL_BUFFER,
45b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    SHARED_BUFFER,
46b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    INLINE_BUFFER
47b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen};
48b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen
49b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissenclass RemoteMediaBufferReleaser : public BBinder {
50b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissenpublic:
51e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    RemoteMediaBufferReleaser(MediaBuffer *buf, sp<BnMediaSource> owner) {
52b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen        mBuf = buf;
53e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia        mOwner = owner;
54b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    }
55b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    ~RemoteMediaBufferReleaser() {
56b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen        if (mBuf) {
57b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            ALOGW("RemoteMediaBufferReleaser dtor called while still holding buffer");
58b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            mBuf->release();
59b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen        }
60b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    }
61b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    virtual status_t    onTransact( uint32_t code,
62b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                                    const Parcel& data,
63b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                                    Parcel* reply,
64b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                                    uint32_t flags = 0) {
65b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen        if (code == RELEASE_BUFFER) {
66b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            mBuf->release();
67b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            mBuf = NULL;
68b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            return OK;
69b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen        } else {
70b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            return BBinder::onTransact(code, data, reply, flags);
71b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen        }
72b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    }
73b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissenprivate:
74b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    MediaBuffer *mBuf;
75e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    // Keep a ref to ensure MediaBuffer is released before the owner, i.e., BnMediaSource,
76e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    // because BnMediaSource needs to delete MediaBufferGroup in its dtor and
77e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    // MediaBufferGroup dtor requires all MediaBuffer's have 0 ref count.
78e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    sp<BnMediaSource> mOwner;
79b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen};
80b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen
81b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen
82b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissenclass RemoteMediaBufferWrapper : public MediaBuffer {
83b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissenpublic:
84b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    RemoteMediaBufferWrapper(sp<IMemory> mem, sp<IBinder> source);
85b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissenprotected:
86b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    virtual ~RemoteMediaBufferWrapper();
87b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissenprivate:
88b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    sp<IMemory> mMemory;
89b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    sp<IBinder> mRemoteSource;
90b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen};
91b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen
92b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco NelissenRemoteMediaBufferWrapper::RemoteMediaBufferWrapper(sp<IMemory> mem, sp<IBinder> source)
93b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen: MediaBuffer(mem->pointer(), mem->size()) {
94b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    mMemory = mem;
95b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    mRemoteSource = source;
96b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen}
97b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen
98b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco NelissenRemoteMediaBufferWrapper::~RemoteMediaBufferWrapper() {
99b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    mMemory.clear();
100b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    // Explicitly ask the remote side to release the buffer. We could also just clear
101b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    // mRemoteSource, but that doesn't immediately release the reference on the remote side.
102b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    Parcel data, reply;
103b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    mRemoteSource->transact(RELEASE_BUFFER, data, &reply);
104b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen    mRemoteSource.clear();
105b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen}
106b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen
107b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenclass BpMediaSource : public BpInterface<IMediaSource> {
108b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenpublic:
109b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    BpMediaSource(const sp<IBinder>& impl)
110b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        : BpInterface<IMediaSource>(impl)
111b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    {
112b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
113b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
114b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual status_t start(MetaData *params) {
115b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("start");
116b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        Parcel data, reply;
117b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
118b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        if (params) {
119b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            params->writeToParcel(data);
120b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
121b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        status_t ret = remote()->transact(START, data, &reply);
122b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        if (ret == NO_ERROR && params) {
123b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGW("ignoring potentially modified MetaData from start");
124b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGW("input:");
125b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            params->dumpToLog();
126b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            sp<MetaData> meta = MetaData::createFromParcel(reply);
127b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGW("output:");
128b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            meta->dumpToLog();
129b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
130b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return ret;
131b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
132b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
133b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual status_t stop() {
134b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("stop");
135b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        Parcel data, reply;
136b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
137b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return remote()->transact(STOP, data, &reply);
138b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
139b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
140b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual sp<MetaData> getFormat() {
141b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("getFormat");
142b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        Parcel data, reply;
143b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
144b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        status_t ret = remote()->transact(GETFORMAT, data, &reply);
145b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        if (ret == NO_ERROR) {
146b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            mMetaData = MetaData::createFromParcel(reply);
147b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return mMetaData;
148b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
149b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return NULL;
150b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
151b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
152b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual status_t read(MediaBuffer **buffer, const ReadOptions *options) {
153b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("read");
154b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        Parcel data, reply;
155b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
156b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        if (options) {
157b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            data.writeByteArray(sizeof(*options), (uint8_t*) options);
158b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
159b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        status_t ret = remote()->transact(READ, data, &reply);
160b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        if (ret != NO_ERROR) {
161b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return ret;
162b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
163b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        // wrap the returned data in a MediaBuffer
164b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ret = reply.readInt32();
165b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen        int32_t buftype = reply.readInt32();
166b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen        if (buftype == SHARED_BUFFER) {
167b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            sp<IBinder> remote = reply.readStrongBinder();
168b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            sp<IBinder> binder = reply.readStrongBinder();
169b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            sp<IMemory> mem = interface_cast<IMemory>(binder);
170b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            if (mem == NULL) {
171b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                ALOGE("received NULL IMemory for shared buffer");
172b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            }
173b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            size_t offset = reply.readInt32();
174b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            size_t length = reply.readInt32();
175b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            MediaBuffer *buf = new RemoteMediaBufferWrapper(mem, remote);
176b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            buf->set_range(offset, length);
177b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            buf->meta_data()->updateFromParcel(reply);
178b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            *buffer = buf;
179b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen        } else if (buftype == NULL_BUFFER) {
180b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            ALOGV("got status %d and NULL buffer", ret);
181b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            *buffer = NULL;
182b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        } else {
183b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen            int32_t len = reply.readInt32();
184b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGV("got status %d and len %d", ret, len);
185b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            *buffer = new MediaBuffer(len);
186b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            reply.read((*buffer)->data(), len);
187b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            (*buffer)->meta_data()->updateFromParcel(reply);
188b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
189b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return ret;
190b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
191b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
192b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual status_t pause() {
193b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("pause");
194b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        Parcel data, reply;
195b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
196b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return remote()->transact(PAUSE, data, &reply);
197b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
198b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
199b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual status_t setBuffers(const Vector<MediaBuffer *> & buffers __unused) {
200b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        ALOGV("setBuffers NOT IMPLEMENTED");
201b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return ERROR_UNSUPPORTED; // default
202b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
203b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
204b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenprivate:
205b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    // NuPlayer passes pointers-to-metadata around, so we use this to keep the metadata alive
206b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    // XXX: could we use this for caching, or does metadata change on the fly?
207b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    sp<MetaData> mMetaData;
208b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
209b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen};
210b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
211b2487f03f12dcafdb801fc0007c8df8412397f44Marco NelissenIMPLEMENT_META_INTERFACE(MediaSource, "android.media.IMediaSource");
212b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
213b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#undef LOG_TAG
214b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define LOG_TAG "BnMediaSource"
215b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
216e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei JiaBnMediaSource::BnMediaSource()
217e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    : mGroup(NULL) {
218e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia}
219e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
220e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei JiaBnMediaSource::~BnMediaSource() {
221e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    delete mGroup;
222e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia    mGroup = NULL;
223e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia}
224e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
225b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatus_t BnMediaSource::onTransact(
226b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
227b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen{
228b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    switch (code) {
229b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        case START: {
230b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGV("start");
231b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            CHECK_INTERFACE(IMediaSource, data, reply);
232b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            sp<MetaData> meta;
233b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            if (data.dataAvail()) {
234b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                meta = MetaData::createFromParcel(data);
235b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            }
236b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            status_t ret = start(meta.get());
237b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            if (ret == NO_ERROR && meta != NULL) {
238b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                meta->writeToParcel(*reply);
239b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            }
240b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return ret;
241b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
242b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        case STOP: {
243b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGV("stop");
244b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            CHECK_INTERFACE(IMediaSource, data, reply);
245b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return stop();
246b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
247b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        case PAUSE: {
248b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGV("pause");
249b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            CHECK_INTERFACE(IMediaSource, data, reply);
250b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return pause();
251b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
252b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        case GETFORMAT: {
253b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGV("getFormat");
254b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            CHECK_INTERFACE(IMediaSource, data, reply);
255b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            sp<MetaData> meta = getFormat();
256b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            if (meta != NULL) {
257b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                meta->writeToParcel(*reply);
258b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                return NO_ERROR;
259b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            }
260b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return UNKNOWN_ERROR;
261b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
262b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        case READ: {
263b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ALOGV("read");
264b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            CHECK_INTERFACE(IMediaSource, data, reply);
265b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            status_t ret;
266b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            MediaBuffer *buf = NULL;
267b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ReadOptions opts;
268b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            uint32_t len;
269b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            if (data.readUint32(&len) == NO_ERROR &&
270b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                    len == sizeof(opts) && data.read((void*)&opts, len) == NO_ERROR) {
271b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                ret = read(&buf, &opts);
272b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            } else {
273b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                ret = read(&buf, NULL);
274b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            }
275b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen
276b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            reply->writeInt32(ret);
277b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            if (buf != NULL) {
278b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                size_t usedSize = buf->range_length();
279b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                // even if we're using shared memory, we might not want to use it, since for small
280b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                // sizes it's faster to copy data through the Binder transaction
281e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                // On the other hand, if the data size is large enough, it's better to use shared
282e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                // memory. When data is too large, binder can't handle it.
283e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                if (usedSize >= MediaBuffer::kSharedMemThreshold) {
284e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                    ALOGV("use shared memory: %zu", usedSize);
285e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
286e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                    MediaBuffer *transferBuf = buf;
287e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                    size_t offset = buf->range_offset();
288e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                    if (transferBuf->mMemory == NULL) {
289e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                        if (mGroup == NULL) {
290e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                            mGroup = new MediaBufferGroup;
291e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                            size_t allocateSize = usedSize;
292e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                            if (usedSize < SIZE_MAX / 3) {
293e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                                allocateSize = usedSize * 3 / 2;
294e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                            }
295e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                            mGroup->add_buffer(new MediaBuffer(allocateSize));
296e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                        }
297e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
298e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                        ret = mGroup->acquire_buffer(
299e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                                &transferBuf, false /* nonBlocking */, usedSize);
300e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                        if (ret != OK || transferBuf == NULL || transferBuf->mMemory == NULL) {
301e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                            ALOGW("failed to acquire shared memory, ret %d", ret);
302e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                            reply->writeInt32(NULL_BUFFER);
303e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                            return NO_ERROR;
304e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                        }
305e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                        memcpy(transferBuf->data(), (uint8_t*)buf->data() + buf->range_offset(),
306e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                                buf->range_length());
307e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                        offset = 0;
308e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                    }
309e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia
310b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                    reply->writeInt32(SHARED_BUFFER);
311e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                    RemoteMediaBufferReleaser *wrapper =
312e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                        new RemoteMediaBufferReleaser(transferBuf, this);
313b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                    reply->writeStrongBinder(wrapper);
314e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                    reply->writeStrongBinder(IInterface::asBinder(transferBuf->mMemory));
315e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                    reply->writeInt32(offset);
316b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                    reply->writeInt32(usedSize);
317b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                    buf->meta_data()->writeToParcel(*reply);
3181d5a306c0b1322168e8f9fcf81876118a355a400Wei Jia                    if (buf->mMemory == NULL) {
3191d5a306c0b1322168e8f9fcf81876118a355a400Wei Jia                        buf->release();
3201d5a306c0b1322168e8f9fcf81876118a355a400Wei Jia                    }
321b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                } else {
322e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia                    // buffer is small: copy it
323b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                    if (buf->mMemory != NULL) {
324b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                        ALOGV("%zu shared mem available, but only %zu used", buf->mMemory->size(), buf->range_length());
325b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                    }
326b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                    reply->writeInt32(INLINE_BUFFER);
327b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                    reply->writeByteArray(buf->range_length(), (uint8_t*)buf->data() + buf->range_offset());
328b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                    buf->meta_data()->writeToParcel(*reply);
329b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                    buf->release();
330b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                }
331b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            } else {
332b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                ALOGV("ret %d, buf %p", ret, buf);
333b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen                reply->writeInt32(NULL_BUFFER);
334b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            }
335b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return NO_ERROR;
336b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        }
337b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        default:
338b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            return BBinder::onTransact(code, data, reply, flags);
339b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
340b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
341b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
342b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen////////////////////////////////////////////////////////////////////////////////
343b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
344b2487f03f12dcafdb801fc0007c8df8412397f44Marco NelissenIMediaSource::ReadOptions::ReadOptions() {
345b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    reset();
346b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
347b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
348b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenvoid IMediaSource::ReadOptions::reset() {
349b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mOptions = 0;
350b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mSeekTimeUs = 0;
351b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mLatenessUs = 0;
352b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mNonBlocking = false;
353b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
354b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
355b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenvoid IMediaSource::ReadOptions::setNonBlocking() {
356b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mNonBlocking = true;
357b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
358b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
359b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenvoid IMediaSource::ReadOptions::clearNonBlocking() {
360b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mNonBlocking = false;
361b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
362b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
363b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenbool IMediaSource::ReadOptions::getNonBlocking() const {
364b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return mNonBlocking;
365b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
366b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
367b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenvoid IMediaSource::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
368b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mOptions |= kSeekTo_Option;
369b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mSeekTimeUs = time_us;
370b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mSeekMode = mode;
371b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
372b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
373b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenvoid IMediaSource::ReadOptions::clearSeekTo() {
374b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mOptions &= ~kSeekTo_Option;
375b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mSeekTimeUs = 0;
376b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mSeekMode = SEEK_CLOSEST_SYNC;
377b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
378b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
379b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenbool IMediaSource::ReadOptions::getSeekTo(
380b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        int64_t *time_us, SeekMode *mode) const {
381b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    *time_us = mSeekTimeUs;
382b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    *mode = mSeekMode;
383b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return (mOptions & kSeekTo_Option) != 0;
384b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
385b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
386b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenvoid IMediaSource::ReadOptions::setLateBy(int64_t lateness_us) {
387b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    mLatenessUs = lateness_us;
388b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
389b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
390b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenint64_t IMediaSource::ReadOptions::getLateBy() const {
391b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return mLatenessUs;
392b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
393b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
394b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
395b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}  // namespace android
396b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
397