Implement server side playback timestamps with 64 bit accuracy
Provide server timestamps if the HAL doesn't provide it.
Provide monotonic - boottime translation.
Integrate record timestamps and playback timestamps together.
Bug: 17472992
Bug: 22871200
Bug: 26400089
Bug: 26682703
Change-Id: If1974f94232fcce7ba0bbcdf63d9e54ed51918ff
diff --git a/include/media/ExtendedAudioBufferProvider.h b/include/media/ExtendedAudioBufferProvider.h
index 2539ed3..168ceed 100644
--- a/include/media/ExtendedAudioBufferProvider.h
+++ b/include/media/ExtendedAudioBufferProvider.h
@@ -27,11 +27,11 @@
virtual size_t framesReady() const = 0; // see description at AudioFlinger.h
// Return the total number of frames that have been obtained and released
- virtual size_t framesReleased() const { return 0; }
+ virtual int64_t framesReleased() const { return 0; }
// Invoked by buffer consumer when a new timestamp is available.
// Default implementation ignores the timestamp.
- virtual void onTimestamp(const AudioTimestamp& timestamp) { }
+ virtual void onTimestamp(const ExtendedTimestamp& timestamp) { }
};
} // namespace android
diff --git a/include/media/nbaio/AudioStreamInSource.h b/include/media/nbaio/AudioStreamInSource.h
index eaea63c..a6e7992 100644
--- a/include/media/nbaio/AudioStreamInSource.h
+++ b/include/media/nbaio/AudioStreamInSource.h
@@ -38,8 +38,8 @@
// NBAIO_Sink interface
//virtual size_t framesRead() const;
- virtual size_t framesOverrun();
- virtual size_t overruns() { (void) framesOverrun(); return mOverruns; }
+ virtual int64_t framesOverrun();
+ virtual int64_t overruns() { (void) framesOverrun(); return mOverruns; }
// This is an over-estimate, and could dupe the caller into making a blocking read()
// FIXME Use an audio HAL API to query the buffer filling status when it's available.
@@ -56,8 +56,8 @@
private:
audio_stream_in * const mStream;
size_t mStreamBufferSizeBytes; // as reported by get_buffer_size()
- size_t mFramesOverrun;
- size_t mOverruns;
+ int64_t mFramesOverrun;
+ int64_t mOverruns;
};
} // namespace android
diff --git a/include/media/nbaio/AudioStreamOutSink.h b/include/media/nbaio/AudioStreamOutSink.h
index 0998d45..e86b018 100644
--- a/include/media/nbaio/AudioStreamOutSink.h
+++ b/include/media/nbaio/AudioStreamOutSink.h
@@ -47,7 +47,7 @@
virtual ssize_t write(const void *buffer, size_t count);
- virtual status_t getTimestamp(AudioTimestamp& timestamp);
+ virtual status_t getTimestamp(ExtendedTimestamp ×tamp);
// NBAIO_Sink end
diff --git a/include/media/nbaio/MonoPipe.h b/include/media/nbaio/MonoPipe.h
index df9cafe..d2cd218 100644
--- a/include/media/nbaio/MonoPipe.h
+++ b/include/media/nbaio/MonoPipe.h
@@ -23,7 +23,7 @@
namespace android {
-typedef SingleStateQueue<AudioTimestamp> AudioTimestampSingleStateQueue;
+typedef SingleStateQueue<ExtendedTimestamp> ExtendedTimestampSingleStateQueue;
// MonoPipe is similar to Pipe except:
// - supports only a single reader, called MonoPipeReader
@@ -51,9 +51,9 @@
// NBAIO_Sink interface
- //virtual size_t framesWritten() const;
- //virtual size_t framesUnderrun() const;
- //virtual size_t underruns() const;
+ //virtual int64_t framesWritten() const;
+ //virtual int64_t framesUnderrun() const;
+ //virtual int64_t underruns() const;
virtual ssize_t availableToWrite() const;
virtual ssize_t write(const void *buffer, size_t count);
@@ -77,7 +77,7 @@
bool isShutdown();
// Return NO_ERROR if there is a timestamp available
- status_t getTimestamp(AudioTimestamp& timestamp);
+ status_t getTimestamp(ExtendedTimestamp ×tamp);
private:
const size_t mReqFrames; // as requested in constructor, unrounded
@@ -97,9 +97,9 @@
bool mIsShutdown; // whether shutdown(true) was called, no barriers are needed
- AudioTimestampSingleStateQueue::Shared mTimestampShared;
- AudioTimestampSingleStateQueue::Mutator mTimestampMutator;
- AudioTimestampSingleStateQueue::Observer mTimestampObserver;
+ ExtendedTimestampSingleStateQueue::Shared mTimestampShared;
+ ExtendedTimestampSingleStateQueue::Mutator mTimestampMutator;
+ ExtendedTimestampSingleStateQueue::Observer mTimestampObserver;
};
} // namespace android
diff --git a/include/media/nbaio/MonoPipeReader.h b/include/media/nbaio/MonoPipeReader.h
index 4a7c3c5..b3c891d 100644
--- a/include/media/nbaio/MonoPipeReader.h
+++ b/include/media/nbaio/MonoPipeReader.h
@@ -49,7 +49,7 @@
virtual ssize_t read(void *buffer, size_t count);
- virtual void onTimestamp(const AudioTimestamp& timestamp);
+ virtual void onTimestamp(const ExtendedTimestamp ×tamp);
// NBAIO_Source end
diff --git a/include/media/nbaio/NBAIO.h b/include/media/nbaio/NBAIO.h
index 2f7e291..120de4f 100644
--- a/include/media/nbaio/NBAIO.h
+++ b/include/media/nbaio/NBAIO.h
@@ -145,13 +145,13 @@
// 32 bits rolls over after 27 hours at 44.1 kHz; if that concerns you then poll periodically.
// Return the number of frames written successfully since construction.
- virtual size_t framesWritten() const { return mFramesWritten; }
+ virtual int64_t framesWritten() const { return mFramesWritten; }
// Number of frames lost due to underrun since construction.
- virtual size_t framesUnderrun() const { return 0; }
+ virtual int64_t framesUnderrun() const { return 0; }
// Number of underruns since construction, where a set of contiguous lost frames is one event.
- virtual size_t underruns() const { return 0; }
+ virtual int64_t underruns() const { return 0; }
// Estimate of number of frames that could be written successfully now without blocking.
// When a write() is actually attempted, the implementation is permitted to return a smaller or
@@ -212,7 +212,7 @@
// Returns NO_ERROR if a timestamp is available. The timestamp includes the total number
// of frames presented to an external observer, together with the value of CLOCK_MONOTONIC
// as of this presentation count. The timestamp parameter is undefined if error is returned.
- virtual status_t getTimestamp(AudioTimestamp& timestamp) { return INVALID_OPERATION; }
+ virtual status_t getTimestamp(ExtendedTimestamp ×tamp) { return INVALID_OPERATION; }
protected:
NBAIO_Sink(const NBAIO_Format& format = Format_Invalid) : NBAIO_Port(format), mFramesWritten(0)
@@ -220,7 +220,7 @@
virtual ~NBAIO_Sink() { }
// Implementations are free to ignore these if they don't need them
- size_t mFramesWritten;
+ int64_t mFramesWritten;
};
// Abstract class (interface) representing a non-blocking data source, for use by a data consumer.
@@ -232,15 +232,15 @@
// 32 bits rolls over after 27 hours at 44.1 kHz; if that concerns you then poll periodically.
// Number of frames read successfully since construction.
- virtual size_t framesRead() const { return mFramesRead; }
+ virtual int64_t framesRead() const { return mFramesRead; }
// Number of frames lost due to overrun since construction.
// Not const because implementations may need to do I/O.
- virtual size_t framesOverrun() /*const*/ { return 0; }
+ virtual int64_t framesOverrun() /*const*/ { return 0; }
// Number of overruns since construction, where a set of contiguous lost frames is one event.
// Not const because implementations may need to do I/O.
- virtual size_t overruns() /*const*/ { return 0; }
+ virtual int64_t overruns() /*const*/ { return 0; }
// Estimate of number of frames that could be read successfully now.
// When a read() is actually attempted, the implementation is permitted to return a smaller or
@@ -299,7 +299,7 @@
// Invoked asynchronously by corresponding sink when a new timestamp is available.
// Default implementation ignores the timestamp.
- virtual void onTimestamp(const AudioTimestamp& timestamp) { }
+ virtual void onTimestamp(const ExtendedTimestamp& timestamp) { }
protected:
NBAIO_Source(const NBAIO_Format& format = Format_Invalid) : NBAIO_Port(format), mFramesRead(0)
@@ -307,7 +307,7 @@
virtual ~NBAIO_Source() { }
// Implementations are free to ignore these if they don't need them
- size_t mFramesRead;
+ int64_t mFramesRead;
};
} // namespace android
diff --git a/include/media/nbaio/Pipe.h b/include/media/nbaio/Pipe.h
index eba37bc..cc95ff7 100644
--- a/include/media/nbaio/Pipe.h
+++ b/include/media/nbaio/Pipe.h
@@ -45,9 +45,9 @@
// NBAIO_Sink interface
- //virtual size_t framesWritten() const;
- //virtual size_t framesUnderrun() const;
- //virtual size_t underruns() const;
+ //virtual int64_t framesWritten() const;
+ //virtual int64_t framesUnderrun() const;
+ //virtual int64_t underruns() const;
// The write side of a pipe permits overruns; flow control is the caller's responsibility.
// It doesn't return +infinity because that would guarantee an overrun.
diff --git a/include/media/nbaio/PipeReader.h b/include/media/nbaio/PipeReader.h
index 398353b..7c733ad 100644
--- a/include/media/nbaio/PipeReader.h
+++ b/include/media/nbaio/PipeReader.h
@@ -40,8 +40,8 @@
// NBAIO_Source interface
//virtual size_t framesRead() const;
- virtual size_t framesOverrun() { return mFramesOverrun; }
- virtual size_t overruns() { return mOverruns; }
+ virtual int64_t framesOverrun() { return mFramesOverrun; }
+ virtual int64_t overruns() { return mOverruns; }
virtual ssize_t availableToRead();
@@ -56,8 +56,8 @@
private:
Pipe& mPipe;
int32_t mFront; // follows behind mPipe.mRear
- size_t mFramesOverrun;
- size_t mOverruns;
+ int64_t mFramesOverrun;
+ int64_t mOverruns;
};
} // namespace android
diff --git a/include/media/nbaio/SourceAudioBufferProvider.h b/include/media/nbaio/SourceAudioBufferProvider.h
index 29172e1..ae49903 100644
--- a/include/media/nbaio/SourceAudioBufferProvider.h
+++ b/include/media/nbaio/SourceAudioBufferProvider.h
@@ -36,8 +36,8 @@
// ExtendedAudioBufferProvider interface
virtual size_t framesReady() const;
- virtual size_t framesReleased() const;
- virtual void onTimestamp(const AudioTimestamp& timestamp);
+ virtual int64_t framesReleased() const;
+ virtual void onTimestamp(const ExtendedTimestamp ×tamp);
private:
const sp<NBAIO_Source> mSource; // the wrapped source
@@ -47,7 +47,7 @@
size_t mOffset; // frame offset within mAllocated of valid data
size_t mRemaining; // frame count within mAllocated of valid data
size_t mGetCount; // buffer.frameCount of the most recent getNextBuffer
- uint32_t mFramesReleased; // counter of the total number of frames released
+ int64_t mFramesReleased; // counter of the total number of frames released
};
} // namespace android
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index aa9e98c..ea8a78e 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -176,6 +176,7 @@
// server write-only, client read
ExtendedTimestampQueue::Shared mExtendedTimestampQueue;
+
public:
volatile int32_t mFlags; // combinations of CBLK_*
@@ -532,7 +533,7 @@
size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
: ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer),
mPlaybackRateObserver(&cblk->mPlaybackRateQueue),
- mUnderrunCount(0), mUnderrunning(false) {
+ mUnderrunCount(0), mUnderrunning(false), mDrained(true) {
mCblk->mSampleRate = sampleRate;
mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
}
@@ -569,6 +570,18 @@
// Return the playback speed and pitch read atomically. Not multi-thread safe on server side.
AudioPlaybackRate getPlaybackRate();
+ // Set the internal drain state of the track buffer from the timestamp received.
+ virtual void setDrained(bool drained) {
+ mDrained.store(drained);
+ }
+
+ // Check if the internal drain state of the track buffer.
+ // This is not a guarantee, but advisory for determining whether the track is
+ // fully played out.
+ virtual bool isDrained() const {
+ return mDrained.load();
+ }
+
private:
AudioPlaybackRate mPlaybackRate; // last observed playback rate
PlaybackRateQueue::Observer mPlaybackRateObserver;
@@ -576,6 +589,8 @@
// The server keeps a copy here where it is safe from the client.
uint32_t mUnderrunCount; // echoed to mCblk
bool mUnderrunning; // used to detect edge of underrun
+
+ std::atomic<bool> mDrained; // is the track buffer drained
};
class StaticAudioTrackServerProxy : public AudioTrackServerProxy {