1e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman/*
2e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Copyright (C) 2009 The Android Open Source Project
3e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman *
4e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Licensed under the Apache License, Version 2.0 (the "License");
5e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * you may not use this file except in compliance with the License.
6e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * You may obtain a copy of the License at
7e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman *
8e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman *      http://www.apache.org/licenses/LICENSE-2.0
9e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman *
10e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * Unless required by applicable law or agreed to in writing, software
11e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * distributed under the License is distributed on an "AS IS" BASIS,
12e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * See the License for the specific language governing permissions and
14e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman * limitations under the License.
15e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman */
16e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
17e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#ifndef IMEDIA_SOURCE_BASE_H_
18e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
19e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#define IMEDIA_SOURCE_BASE_H_
20e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
21e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <map>
22e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
23e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <binder/IInterface.h>
24e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <binder/IMemory.h>
25e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <media/stagefright/MediaBuffer.h>
26e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#include <media/stagefright/MediaErrors.h>
27e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
28e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramannamespace android {
29e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
30e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanstruct MediaSource;
31e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass MetaData;
32e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass MediaBufferGroup;
33e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
34e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass IMediaSource : public IInterface {
35e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanpublic:
36e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    DECLARE_META_INTERFACE(MediaSource);
37e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
38e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    enum {
39e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        // Maximum number of buffers would be read in readMultiple.
40e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        kMaxNumReadMultiple = 128,
41e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    };
42e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
43e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // To be called before any other methods on this object, except
44e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // getFormat().
45e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual status_t start(MetaData *params = NULL) = 0;
46e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
47e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Any blocking read call returns immediately with a result of NO_INIT.
48e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // It is an error to call any methods other than start after this call
49e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // returns. Any buffers the object may be holding onto at the time of
50e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // the stop() call are released.
51e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Also, it is imperative that any buffers output by this object and
52e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // held onto by callers be released before a call to stop() !!!
53e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual status_t stop() = 0;
54e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
55e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Returns the format of the data output by this media source.
56e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual sp<MetaData> getFormat() = 0;
57e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
58e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Options that modify read() behaviour. The default is to
59e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // a) not request a seek
60e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // b) not be late, i.e. lateness_us = 0
61e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    struct ReadOptions {
62e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        enum SeekMode : int32_t {
63e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            SEEK_PREVIOUS_SYNC,
64e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            SEEK_NEXT_SYNC,
65e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            SEEK_CLOSEST_SYNC,
66e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            SEEK_CLOSEST,
67e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        };
68e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
69e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        ReadOptions();
70e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
71e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        // Reset everything back to defaults.
72e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        void reset();
73e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
74e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        void setSeekTo(int64_t time_us, SeekMode mode = SEEK_CLOSEST_SYNC);
75e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        void clearSeekTo();
76e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        bool getSeekTo(int64_t *time_us, SeekMode *mode) const;
77e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
78e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        // TODO: remove this if unused.
79e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        void setLateBy(int64_t lateness_us);
80e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        int64_t getLateBy() const;
81e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
82e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        void setNonBlocking();
83e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        void clearNonBlocking();
84e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        bool getNonBlocking() const;
85e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
86e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        // Used to clear all non-persistent options for multiple buffer reads.
87e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        void clearNonPersistent() {
88e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            clearSeekTo();
89e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        }
90e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
91e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    private:
92e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        enum Options {
93e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            kSeekTo_Option      = 1,
94e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        };
95e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
96e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        uint32_t mOptions;
97e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        int64_t mSeekTimeUs;
98e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        SeekMode mSeekMode;
99e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        int64_t mLatenessUs;
100e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        bool mNonBlocking;
101e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    } __attribute__((packed)); // sent through Binder
102e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
103e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Returns a new buffer of data. Call blocks until a
104e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // buffer is available, an error is encountered or the end of the stream
105e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // is reached.
106e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // End of stream is signalled by a result of ERROR_END_OF_STREAM.
107e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // A result of INFO_FORMAT_CHANGED indicates that the format of this
108e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // MediaSource has changed mid-stream, the client can continue reading
109e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // but should be prepared for buffers of the new configuration.
110e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    //
111e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // TODO: consider removing read() in favor of readMultiple().
112e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual status_t read(
113e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            MediaBuffer **buffer, const ReadOptions *options = NULL) = 0;
114e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
115e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Returns a vector of new buffers of data, where the new buffers are added
116e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // to the end of the vector.
117e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Call blocks until an error is encountered, or the end of the stream is
118e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // reached, or format change is hit, or |kMaxNumReadMultiple| buffers have
119e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // been read.
120e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // End of stream is signaled by a result of ERROR_END_OF_STREAM.
121e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // A result of INFO_FORMAT_CHANGED indicates that the format of this
122e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // MediaSource has changed mid-stream, the client can continue reading
123e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // but should be prepared for buffers of the new configuration.
124e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    //
125e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // ReadOptions may be specified. Persistent options apply to all reads;
126e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // non-persistent options (e.g. seek) apply only to the first read.
127e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual status_t readMultiple(
128e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            Vector<MediaBuffer *> *buffers, uint32_t maxNumBuffers = 1,
129e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            const ReadOptions *options = nullptr) = 0;
130e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
131e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Returns true if |readMultiple| is supported, otherwise false.
132e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual bool supportReadMultiple() = 0;
133e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
134e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Returns true if |read| supports nonblocking option, otherwise false.
135e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // |readMultiple| if supported, always allows the nonblocking option.
136e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual bool supportNonblockingRead() = 0;
137e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
138e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Causes this source to suspend pulling data from its upstream source
139e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // until a subsequent read-with-seek. Currently only supported by
140e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // OMXCodec.
141e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual status_t pause()  = 0;
142e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
143e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // The consumer of this media source requests that the given buffers
144e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // are to be returned exclusively in response to read calls.
145e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // This will be called after a successful start() and before the
146e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // first read() call.
147e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Callee assumes ownership of the buffers if no error is returned.
148e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual status_t setBuffers(const Vector<MediaBuffer *> & /* buffers */) = 0;
149e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
150e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman};
151e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
152e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanclass BnMediaSource: public BnInterface<IMediaSource>
153e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman{
154e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanpublic:
155e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    BnMediaSource();
156e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
157e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual status_t    onTransact(uint32_t code, const Parcel& data, Parcel* reply,
158e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                                uint32_t flags = 0);
159e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
160e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual status_t pause() {
161e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        return ERROR_UNSUPPORTED;
162e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    }
163e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
164e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual status_t setBuffers(const Vector<MediaBuffer *> & /* buffers */) {
165e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        return ERROR_UNSUPPORTED;
166e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    }
167e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
168e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // TODO: Implement this for local media sources.
169e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual status_t readMultiple(
170e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            Vector<MediaBuffer *> * /* buffers */, uint32_t /* maxNumBuffers = 1 */,
171e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            const ReadOptions * /* options = nullptr */) {
172e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        return ERROR_UNSUPPORTED;
173e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    }
174e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
175e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual bool supportReadMultiple() {
176e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        return false;
177e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    }
178e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
179e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // Override in source if nonblocking reads are supported.
180e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual bool supportNonblockingRead() {
181e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        return false;
182e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    }
183e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
184e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    static const size_t kBinderMediaBuffers = 4; // buffers managed by BnMediaSource
185e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    static const size_t kTransferSharedAsSharedThreshold = 4 * 1024;  // if >= shared, else inline
186e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    static const size_t kTransferInlineAsSharedThreshold = 64 * 1024; // if >= shared, else inline
187e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    static const size_t kInlineMaxTransfer = 256 * 1024; // Binder size limited to BINDER_VM_SIZE.
188e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
189e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprotected:
190e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    virtual ~BnMediaSource();
191e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
192e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatramanprivate:
193e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    uint32_t mBuffersSinceStop; // Buffer tracking variable
194e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
195e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    std::unique_ptr<MediaBufferGroup> mGroup;
196e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
197e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // To prevent marshalling IMemory with each read transaction, we cache the IMemory pointer
198e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // into a map.
199e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    //
200e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // This is converted into an index, which is used to identify the associated memory
201e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // on the receiving side.  We hold a reference to the IMemory here to ensure it doesn't
202e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    // change underneath us.
203e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
204e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    struct IndexCache {
205e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        IndexCache() : mIndex(0) { }
206e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
207e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        // Returns the index of the IMemory stored in cache or 0 if not found.
208e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        uint64_t lookup(const sp<IMemory> &mem) {
209e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            auto p = mMemoryToIndex.find(mem.get());
210e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            if (p == mMemoryToIndex.end()) {
211e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                return 0;
212e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            }
213e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            if (MediaBuffer::isDeadObject(p->second.first)) {
214e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                // this object's dead
215e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                ALOGW("Attempting to lookup a dead IMemory");
216e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                (void)mMemoryToIndex.erase(p);
217e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                return 0;
218e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            }
219e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            ALOGW_IF(p->second.first.get() != mem.get(), "Mismatched buffers without reset");
220e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            return p->second.second;
221e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        }
222e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
223e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        // Returns the index of the IMemory stored in the index cache.
224e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        uint64_t insert(const sp<IMemory> &mem) {
225e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            auto p = mMemoryToIndex.find(mem.get());
226e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            if (p == mMemoryToIndex.end()) {
227e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                if (mIndex == UINT64_MAX) {
228e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                    ALOGE("Index overflow");
229e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                    mIndex = 1; // skip overflow condition and hope for the best
230e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                } else {
231e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                    ++mIndex;
232e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                }
233e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                (void)mMemoryToIndex.emplace(// C++11 mem.get(), std::make_pair(mem, mIndex))
234e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                        std::piecewise_construct,
235e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                        std::forward_as_tuple(mem.get()), std::forward_as_tuple(mem, mIndex));
236e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                return mIndex;
237e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            }
238e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            ALOGW("IMemory already inserted into cache");
239e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            return p->second.second;
240e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        }
241e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
242e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        void reset() {
243e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            mMemoryToIndex.clear();
244e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            mIndex = 0;
245e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        }
246e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
247e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        void gc() {
248e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            for (auto it = mMemoryToIndex.begin(); it != mMemoryToIndex.end(); ) {
249e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                if (MediaBuffer::isDeadObject(it->second.first)) {
250e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                    it = mMemoryToIndex.erase(it);
251e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                } else {
252e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                    ++it;
253e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman                }
254e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman            }
255e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        }
256e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
257e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    private:
258e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        uint64_t mIndex;
259e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        // C++14 unordered_map erase on iterator is stable; C++11 has no guarantee.
260e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        // Could key on uintptr_t instead of IMemory *
261e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman        std::map<IMemory *, std::pair<sp<IMemory>, uint64_t>> mMemoryToIndex;
262e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman    } mIndexCache;
263e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman};
264e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
265e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman}  // namespace android
266e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman
267e2b43843fd12783188edd2c54188ea8d26864788Vijay Venkatraman#endif  // IMEDIA_SOURCE_BASE_H_
268