181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* 281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** 381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** Copyright 2012, The Android Open Source Project 481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** 581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** Licensed under the Apache License, Version 2.0 (the "License"); 681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** you may not use this file except in compliance with the License. 781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** You may obtain a copy of the License at 881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** 981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** http://www.apache.org/licenses/LICENSE-2.0 1081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** 1181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** Unless required by applicable law or agreed to in writing, software 1281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** distributed under the License is distributed on an "AS IS" BASIS, 1381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** See the License for the specific language governing permissions and 1581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** limitations under the License. 1681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent*/ 1781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifndef INCLUDING_FROM_AUDIOFLINGER_H 1981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent #error This header file should only be included from AudioFlinger.h 2081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 2181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// base for record and playback 2381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentclass TrackBase : public ExtendedAudioBufferProvider, public RefBase { 2481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentpublic: 2681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent enum track_state { 2781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent IDLE, 2881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FLUSHED, 2981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent STOPPED, 30bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // next 2 states are currently used for fast tracks 31bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // and offloaded tracks only 3281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent STOPPING_1, // waiting for first underrun 3381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent STOPPING_2, // waiting for presentation complete 3481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent RESUMING, 3581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ACTIVE, 3681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PAUSING, 376dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten PAUSED, 386dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten STARTING_1, // for RecordTrack only 396dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten STARTING_2, // for RecordTrack only 4081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent }; 4181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 426181ffd90a436f333c43a7f812391eee2c35005aGlenn Kasten // where to allocate the data buffer 436181ffd90a436f333c43a7f812391eee2c35005aGlenn Kasten enum alloc_type { 446181ffd90a436f333c43a7f812391eee2c35005aGlenn Kasten ALLOC_CBLK, // allocate immediately after control block 456181ffd90a436f333c43a7f812391eee2c35005aGlenn Kasten ALLOC_READONLY, // allocate from a separate read-only heap per thread 466181ffd90a436f333c43a7f812391eee2c35005aGlenn Kasten ALLOC_PIPE, // do not allocate; use the pipe buffer 4783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ALLOC_LOCAL, // allocate a local buffer 4883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ALLOC_NONE, // do not allocate:use the buffer passed to TrackBase constructor 4983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent }; 5083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 5183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent enum track_type { 5283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent TYPE_DEFAULT, 5383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent TYPE_OUTPUT, 5483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent TYPE_PATCH, 556181ffd90a436f333c43a7f812391eee2c35005aGlenn Kasten }; 566181ffd90a436f333c43a7f812391eee2c35005aGlenn Kasten 571bc088a918d7038603230637d640941953b314d4Andy Hung enum { 581bc088a918d7038603230637d640941953b314d4Andy Hung TRACK_NAME_PENDING = -1, 591bc088a918d7038603230637d640941953b314d4Andy Hung TRACK_NAME_FAILURE = -2, 601bc088a918d7038603230637d640941953b314d4Andy Hung }; 611bc088a918d7038603230637d640941953b314d4Andy Hung 6281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent TrackBase(ThreadBase *thread, 6381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<Client>& client, 641f564acca544826daaf7dca44e39cec6016b82fdKevin Rocard const audio_attributes_t& mAttr, 6581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t sampleRate, 6681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_format_t format, 6781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_channel_mask_t channelMask, 6881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t frameCount, 6983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent void *buffer, 708fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung size_t bufferSize, 71d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId, 721f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung uid_t uid, 73d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten bool isOut, 7483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent alloc_type alloc = ALLOC_CBLK, 7520b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent track_type type = TYPE_DEFAULT, 7620b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE); 7781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent virtual ~TrackBase(); 7883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent virtual status_t initCheck() const; 7981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 8081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent virtual status_t start(AudioSystem::sync_event_t event, 81d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t triggerSession) = 0; 8281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent virtual void stop() = 0; 8381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<IMemory> getCblk() const { return mCblkMemory; } 8481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_track_cblk_t* cblk() const { return mCblk; } 85d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId() const { return mSessionId; } 861f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung uid_t uid() const { return mUid; } 876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_port_handle_t portId() const { return mPortId; } 8881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent virtual status_t setSyncEvent(const sp<SyncEvent>& event); 8981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 90d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten sp<IMemory> getBuffers() const { return mBufferMemory; } 9183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent void* buffer() const { return mBuffer; } 928fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung size_t bufferSize() const { return mBufferSize; } 93050677873c10d4da308ac222f8533c96cca3207eEric Laurent virtual bool isFastTrack() const = 0; 9483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent bool isOutputTrack() const { return (mType == TYPE_OUTPUT); } 9583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent bool isPatchTrack() const { return (mType == TYPE_PATCH); } 9683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent bool isExternalTrack() const { return !isOutputTrack() && !isPatchTrack(); } 97d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten 986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent virtual void invalidate() { mIsInvalid = true; } 996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent bool isInvalid() const { return mIsInvalid; } 1006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 101069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard audio_attributes_t attributes() const { return mAttr; } 1026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 10381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentprotected: 104bf49308851509d38dbf3f57d9682a819d9f983c9Mikhail Naganov DISALLOW_COPY_AND_ASSIGN(TrackBase); 10581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 10681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // AudioBufferProvider interface 107d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0; 10881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer); 10981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 11081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // ExtendedAudioBufferProvider interface is only needed for Track, 11181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // but putting it in TrackBase avoids the complexity of virtual inheritance 11281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent virtual size_t framesReady() const { return SIZE_MAX; } 11381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 114c9b2e20f7c9a71e07ef398152709c76079decbcdGlenn Kasten audio_format_t format() const { return mFormat; } 11581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 11681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t channelCount() const { return mChannelCount; } 11781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 11881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_channel_mask_t channelMask() const { return mChannelMask; } 11981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1209f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten virtual uint32_t sampleRate() const { return mSampleRate; } 12181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 12281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool isStopped() const { 12381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return (mState == STOPPED || mState == FLUSHED); 12481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 12581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 126bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // for fast tracks and offloaded tracks only 12781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool isStopping() const { 12881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mState == STOPPING_1 || mState == STOPPING_2; 12981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 13081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool isStopping_1() const { 13181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mState == STOPPING_1; 13281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 13381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool isStopping_2() const { 13481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mState == STOPPING_2; 13581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 13681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 13781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool isTerminated() const { 138bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return mTerminated; 139bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 140bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 141bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent void terminate() { 142bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mTerminated = true; 14381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 14481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1452c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung // Upper case characters are final states. 1462c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung // Lower case characters are transitory. 1472c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung const char *getTrackStateString() const { 1482c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung if (isTerminated()) { 1492c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "T "; 1502c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung } 1512c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung switch (mState) { 1522c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case IDLE: 1532c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "I "; 1542c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case STOPPING_1: // for Fast and Offload 1552c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "s1"; 1562c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case STOPPING_2: // for Fast and Offload 1572c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "s2"; 1582c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case STOPPED: 1592c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "S "; 1602c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case RESUMING: 1612c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "r "; 1622c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case ACTIVE: 1632c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "A "; 1642c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case PAUSING: 1652c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "p "; 1662c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case PAUSED: 1672c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "P "; 1682c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case FLUSHED: 1692c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "F "; 1702c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case STARTING_1: // for RecordTrack 1712c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "r1"; 1722c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung case STARTING_2: // for RecordTrack 1732c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "r2"; 1742c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung default: 1752c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung return "? "; 1762c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung } 1772c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung } 1782c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung 179e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten bool isOut() const { return mIsOut; } 180d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten // true for Track, false for RecordTrack, 18181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // this could be a track type if needed later 18281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 18381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const wp<ThreadBase> mThread; 18481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent /*const*/ sp<Client> mClient; // see explanation at ~TrackBase() why not const 18581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<IMemory> mCblkMemory; 18681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_track_cblk_t* mCblk; 187d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten sp<IMemory> mBufferMemory; // currently non-0 for fast RecordTrack only 18881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent void* mBuffer; // start of track buffer, typically in shared memory 189e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten // except for OutputTrack when it is in local memory 1908fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung size_t mBufferSize; // size of mBuffer in bytes 19181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // we don't really need a lock for these 19281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track_state mState; 1931f564acca544826daaf7dca44e39cec6016b82fdKevin Rocard const audio_attributes_t mAttr; 19481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const uint32_t mSampleRate; // initial sample rate only; for tracks which 19581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // support dynamic rates, the current value is in control block 19681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const audio_format_t mFormat; 19781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const audio_channel_mask_t mChannelMask; 198f6ed423af92a56ef54bba23eba883b1f21448b54Glenn Kasten const uint32_t mChannelCount; 19981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const size_t mFrameSize; // AudioFlinger's view of frame size in shared memory, 20081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // where for AudioTrack (but not AudioRecord), 20181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // 8-bit PCM samples are stored as 16-bit 20281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const size_t mFrameCount;// size of track buffer given at createTrack() or 203f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent // createRecord(), and then adjusted as needed 20481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 205d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten const audio_session_t mSessionId; 2061f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung uid_t mUid; 20781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector < sp<SyncEvent> >mSyncEvents; 208e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten const bool mIsOut; 2095bba2f6916dbe00aea7c0521faa0c6ed42114a75Eric Laurent sp<ServerProxy> mServerProxy; 210da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten const int mId; 211da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten sp<NBAIO_Sink> mTeeSink; 212da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten sp<NBAIO_Source> mTeeSource; 213bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent bool mTerminated; 21483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent track_type mType; // must be one of TYPE_DEFAULT, TYPE_OUTPUT, TYPE_PATCH ... 215aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent audio_io_handle_t mThreadIoHandle; // I/O handle of the thread the track is attached to 21620b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent audio_port_handle_t mPortId; // unique ID for this track used by audio policy 2176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent bool mIsInvalid; // non-resettable latch, set by invalidate() 21883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}; 21983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 22083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent// PatchProxyBufferProvider interface is implemented by PatchTrack and PatchRecord. 22183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent// it provides buffer access methods that map those of a ClientProxy (see AudioTrackShared.h) 22283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentclass PatchProxyBufferProvider 22383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 22483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentpublic: 22583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 22683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent virtual ~PatchProxyBufferProvider() {} 22783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 22883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent virtual status_t obtainBuffer(Proxy::Buffer* buffer, 22983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent const struct timespec *requested = NULL) = 0; 23083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent virtual void releaseBuffer(Proxy::Buffer* buffer) = 0; 23181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}; 232