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