and implement them in SourceAudioBufferProvider using the associated NBAIO_Source,
and in Track using the associated AudioTrackServerProxy.
Change-Id: I60dc4adba63fc1dc452ff16caf347e4a7c8242c2
#define ANDROID_EXTENDED_AUDIO_BUFFER_PROVIDER_H
#include <media/AudioBufferProvider.h>
+#include <media/AudioTimestamp.h>
namespace android {
class ExtendedAudioBufferProvider : public AudioBufferProvider {
public:
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; }
+
+ // Invoked by buffer consumer when a new timestamp is available.
+ // Default implementation ignores the timestamp.
+ virtual void onTimestamp(const AudioTimestamp& timestamp) { }
};
} // namespace android
// ExtendedAudioBufferProvider interface
virtual size_t framesReady() const;
+ virtual size_t framesReleased() const;
+ virtual void onTimestamp(const AudioTimestamp& timestamp);
private:
const sp<NBAIO_Source> mSource; // the wrapped source
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
};
} // namespace android
SourceAudioBufferProvider::SourceAudioBufferProvider(const sp<NBAIO_Source>& source) :
mSource(source),
// mFrameBitShiftFormat below
- mAllocated(NULL), mSize(0), mOffset(0), mRemaining(0), mGetCount(0)
+ mAllocated(NULL), mSize(0), mOffset(0), mRemaining(0), mGetCount(0), mFramesReleased(0)
{
ALOG_ASSERT(source != 0);
(mOffset + mRemaining <= mSize));
mOffset += buffer->frameCount;
mRemaining -= buffer->frameCount;
+ mFramesReleased += buffer->frameCount;
buffer->raw = NULL;
buffer->frameCount = 0;
mGetCount = 0;
return avail < 0 ? 0 : (size_t) avail;
}
+size_t SourceAudioBufferProvider::framesReleased() const
+{
+ return mFramesReleased;
+}
+
+void SourceAudioBufferProvider::onTimestamp(const AudioTimestamp& timestamp)
+{
+ mSource->onTimestamp(timestamp);
+}
+
} // namespace android
int64_t pts = kInvalidPTS);
// releaseBuffer() not overridden
+ // ExtendedAudioBufferProvider interface
virtual size_t framesReady() const;
+ virtual size_t framesReleased() const;
bool isPausing() const { return mState == PAUSING; }
bool isPaused() const { return mState == PAUSED; }
return status;
}
+// releaseBuffer() is not overridden
+
+// ExtendedAudioBufferProvider interface
+
// Note that framesReady() takes a mutex on the control block using tryLock().
// This could result in priority inversion if framesReady() is called by the normal mixer,
// as the normal mixer thread runs at lower
return mAudioTrackServerProxy->framesReady();
}
+size_t AudioFlinger::PlaybackThread::Track::framesReleased() const
+{
+ return mAudioTrackServerProxy->framesReleased();
+}
+
// Don't call for fast tracks; the framesReady() could result in priority inversion
bool AudioFlinger::PlaybackThread::Track::isReady() const {
if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {