1010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten/* 2010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Copyright (C) 2012 The Android Open Source Project 3010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * 4010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * you may not use this file except in compliance with the License. 6010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * You may obtain a copy of the License at 7010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * 8010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * 10010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Unless required by applicable law or agreed to in writing, software 11010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * See the License for the specific language governing permissions and 14010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * limitations under the License. 15010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten */ 16010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 17010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#ifndef ANDROID_AUDIO_MONO_PIPE_H 18010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#define ANDROID_AUDIO_MONO_PIPE_H 19010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 20010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include <time.h> 212c3b2da3049627264b7c6b449a1622f002210f03John Grossman#include <utils/LinearTransform.h> 22010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include "NBAIO.h" 23a07a1c2c91dc7ee6ded319262499f20cd01edcf7Glenn Kasten#include <media/SingleStateQueue.h> 24010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 25010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastennamespace android { 26010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 27a07a1c2c91dc7ee6ded319262499f20cd01edcf7Glenn Kastentypedef SingleStateQueue<AudioTimestamp> AudioTimestampSingleStateQueue; 28a07a1c2c91dc7ee6ded319262499f20cd01edcf7Glenn Kasten 29010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// MonoPipe is similar to Pipe except: 30010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// - supports only a single reader, called MonoPipeReader 31010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// - write() cannot overrun; instead it will return a short actual count if insufficient space 32010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// - write() can optionally block if the pipe is full 33010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// Like Pipe, it is not multi-thread safe for either writer or reader 34010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// but writer and reader can be different threads. 35010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenclass MonoPipe : public NBAIO_Sink { 36010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 37010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten friend class MonoPipeReader; 38010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 39010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenpublic: 40820ba70df8ba595ae9055dfd34fdbfa32f70f14dGlenn Kasten // reqFrames will be rounded up to a power of 2, and all slots are available. Must be >= 2. 41010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // Note: whatever shares this object with another thread needs to do so in an SMP-safe way (like 42010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // creating it the object before creating the other thread, or storing the object with a 43010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // release_store). Otherwise the other thread could see a partially-constructed object. 44820ba70df8ba595ae9055dfd34fdbfa32f70f14dGlenn Kasten MonoPipe(size_t reqFrames, NBAIO_Format format, bool writeCanBlock = false); 45010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten virtual ~MonoPipe(); 46010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 47010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // NBAIO_Port interface 48010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 49010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers, 50010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // NBAIO_Format counterOffers[], size_t& numCounterOffers); 51010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual NBAIO_Format format() const; 52010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 53010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // NBAIO_Sink interface 54010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 55010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual size_t framesWritten() const; 56010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual size_t framesUnderrun() const; 57010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual size_t underruns() const; 58010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 59010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten virtual ssize_t availableToWrite() const; 60010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten virtual ssize_t write(const void *buffer, size_t count); 61010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten //virtual ssize_t writeVia(writeVia_t via, size_t total, void *user, size_t block); 62010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 632c3b2da3049627264b7c6b449a1622f002210f03John Grossman // MonoPipe's implementation of getNextWriteTimestamp works in conjunction 642c3b2da3049627264b7c6b449a1622f002210f03John Grossman // with MonoPipeReader. Every time a MonoPipeReader reads from the pipe, it 652c3b2da3049627264b7c6b449a1622f002210f03John Grossman // receives a "readPTS" indicating the point in time for which the reader 662c3b2da3049627264b7c6b449a1622f002210f03John Grossman // would like to read data. This "last read PTS" is offset by the amt of 672c3b2da3049627264b7c6b449a1622f002210f03John Grossman // data the reader is currently mixing and then cached cached along with the 682c3b2da3049627264b7c6b449a1622f002210f03John Grossman // updated read pointer. This cached value is the local time for which the 692c3b2da3049627264b7c6b449a1622f002210f03John Grossman // reader is going to request data next time it reads data (assuming we are 702c3b2da3049627264b7c6b449a1622f002210f03John Grossman // in steady state and operating with no underflows). Writers to the 712c3b2da3049627264b7c6b449a1622f002210f03John Grossman // MonoPipe who would like to know when their next write operation will hit 722c3b2da3049627264b7c6b449a1622f002210f03John Grossman // the speakers can call getNextWriteTimestamp which will return the value 732c3b2da3049627264b7c6b449a1622f002210f03John Grossman // of the last read PTS plus the duration of the amt of data waiting to be 742c3b2da3049627264b7c6b449a1622f002210f03John Grossman // read in the MonoPipe. 752c3b2da3049627264b7c6b449a1622f002210f03John Grossman virtual status_t getNextWriteTimestamp(int64_t *timestamp); 762c3b2da3049627264b7c6b449a1622f002210f03John Grossman 77e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent // average number of frames present in the pipe under normal conditions. 78e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent // See throttling mechanism in MonoPipe::write() 7928ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten size_t getAvgFrames() const { return mSetpoint; } 8028ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten void setAvgFrames(size_t setpoint); 8128ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten size_t maxFrames() const { return mMaxFrames; } 82e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent 83003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten // Set the shutdown state for the write side of a pipe. 84003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten // This may be called by an unrelated thread. When shutdown state is 'true', 85003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten // a write that would otherwise block instead returns a short transfer count. 86003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten // There is no guarantee how long it will take for the shutdown to be recognized, 87003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten // but it will not be an unbounded amount of time. 88003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten // The state can be restored to normal by calling shutdown(false). 89003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten void shutdown(bool newState = true); 90003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten 91003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten // Return true if the write side of a pipe is currently shutdown. 92003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten bool isShutdown(); 93003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten 94767094dd98b01baf21de2ad09c27b3c98776cf73Glenn Kasten // Return NO_ERROR if there is a timestamp available 95767094dd98b01baf21de2ad09c27b3c98776cf73Glenn Kasten status_t getTimestamp(AudioTimestamp& timestamp); 96767094dd98b01baf21de2ad09c27b3c98776cf73Glenn Kasten 97010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenprivate: 982c3b2da3049627264b7c6b449a1622f002210f03John Grossman // A pair of methods and a helper variable which allows the reader and the 992c3b2da3049627264b7c6b449a1622f002210f03John Grossman // writer to update and observe the values of mFront and mNextRdPTS in an 1002c3b2da3049627264b7c6b449a1622f002210f03John Grossman // atomic lock-less fashion. 1012c3b2da3049627264b7c6b449a1622f002210f03John Grossman // 1022c3b2da3049627264b7c6b449a1622f002210f03John Grossman // :: Important :: 1032c3b2da3049627264b7c6b449a1622f002210f03John Grossman // Two assumptions must be true in order for this lock-less approach to 1042c3b2da3049627264b7c6b449a1622f002210f03John Grossman // function properly on all systems. First, there may only be one updater 1052c3b2da3049627264b7c6b449a1622f002210f03John Grossman // thread in the system. Second, the updater thread must be running at a 1062c3b2da3049627264b7c6b449a1622f002210f03John Grossman // strictly higher priority than the observer threads. Currently, both of 1072c3b2da3049627264b7c6b449a1622f002210f03John Grossman // these assumptions are true. The only updater is always a single 1082c3b2da3049627264b7c6b449a1622f002210f03John Grossman // FastMixer thread (which runs with SCHED_FIFO/RT priority while the only 1092c3b2da3049627264b7c6b449a1622f002210f03John Grossman // observer is always an AudioFlinger::PlaybackThread running with 1102c3b2da3049627264b7c6b449a1622f002210f03John Grossman // traditional (non-RT) audio priority. 1112c3b2da3049627264b7c6b449a1622f002210f03John Grossman void updateFrontAndNRPTS(int32_t newFront, int64_t newNextRdPTS); 1122c3b2da3049627264b7c6b449a1622f002210f03John Grossman void observeFrontAndNRPTS(int32_t *outFront, int64_t *outNextRdPTS); 1132c3b2da3049627264b7c6b449a1622f002210f03John Grossman volatile int32_t mUpdateSeq; 1142c3b2da3049627264b7c6b449a1622f002210f03John Grossman 115820ba70df8ba595ae9055dfd34fdbfa32f70f14dGlenn Kasten const size_t mReqFrames; // as requested in constructor, unrounded 116010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten const size_t mMaxFrames; // always a power of 2 117010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten void * const mBuffer; 118010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // mFront and mRear will never be separated by more than mMaxFrames. 119010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // 32-bit overflow is possible if the pipe is active for a long time, but if that happens it's 120010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // safe because we "&" with (mMaxFrames-1) at end of computations to calculate a buffer index. 1212c3b2da3049627264b7c6b449a1622f002210f03John Grossman volatile int32_t mFront; // written by the reader with updateFrontAndNRPTS, observed by 1222c3b2da3049627264b7c6b449a1622f002210f03John Grossman // the writer with observeFrontAndNRPTS 123010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten volatile int32_t mRear; // written by writer with android_atomic_release_store, 124010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // read by reader with android_atomic_acquire_load 1252c3b2da3049627264b7c6b449a1622f002210f03John Grossman volatile int64_t mNextRdPTS; // written by the reader with updateFrontAndNRPTS, observed by 1262c3b2da3049627264b7c6b449a1622f002210f03John Grossman // the writer with observeFrontAndNRPTS 12728ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten bool mWriteTsValid; // whether mWriteTs is valid 12828ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten struct timespec mWriteTs; // time that the previous write() completed 12928ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten size_t mSetpoint; // target value for pipe fill depth 130010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten const bool mWriteCanBlock; // whether write() should block if the pipe is full 1312c3b2da3049627264b7c6b449a1622f002210f03John Grossman 1322c3b2da3049627264b7c6b449a1622f002210f03John Grossman int64_t offsetTimestampByAudioFrames(int64_t ts, size_t audFrames); 1332c3b2da3049627264b7c6b449a1622f002210f03John Grossman LinearTransform mSamplesToLocalTime; 134003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten 135003d9f71937070791418bf7efc1f7fe1e4c6b821Glenn Kasten bool mIsShutdown; // whether shutdown(true) was called, no barriers are needed 136a07a1c2c91dc7ee6ded319262499f20cd01edcf7Glenn Kasten 137a07a1c2c91dc7ee6ded319262499f20cd01edcf7Glenn Kasten AudioTimestampSingleStateQueue::Shared mTimestampShared; 138a07a1c2c91dc7ee6ded319262499f20cd01edcf7Glenn Kasten AudioTimestampSingleStateQueue::Mutator mTimestampMutator; 139a07a1c2c91dc7ee6ded319262499f20cd01edcf7Glenn Kasten AudioTimestampSingleStateQueue::Observer mTimestampObserver; 140010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten}; 141010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 142010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} // namespace android 143010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 144010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#endif // ANDROID_AUDIO_MONO_PIPE_H 145