Merge "Send client / device format in recording callback" into nyc-dev
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 4ee8d6c..dbc6e6e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -197,6 +197,7 @@
BatteryNotifier::getInstance().noteResetAudio();
#ifdef TEE_SINK
+ char value[PROPERTY_VALUE_MAX];
(void) property_get("ro.debuggable", value, "0");
int debuggable = atoi(value);
int teeEnabled = 0;
@@ -2878,7 +2879,7 @@
// failures at unlink() which are ignored. It's also unlikely since
// normally dumpsys is only done by bugreport or from the command line.
char teePath[32+256];
- strcpy(teePath, "/data/misc/media");
+ strcpy(teePath, "/data/misc/audioserver");
size_t teePathLen = strlen(teePath);
DIR *dir = opendir(teePath);
teePath[teePathLen++] = '/';
@@ -2920,7 +2921,8 @@
}
} else {
if (fd >= 0) {
- dprintf(fd, "unable to rotate tees in %s: %s\n", teePath, strerror(errno));
+ dprintf(fd, "unable to rotate tees in %.*s: %s\n", teePathLen, teePath,
+ strerror(errno));
}
}
char teeTime[16];
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index e0d8f75..e056ef2 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1565,6 +1565,7 @@
mEffectBufferFormat(AUDIO_FORMAT_INVALID),
mEffectBufferValid(false),
mSuspended(0), mBytesWritten(0),
+ mFramesWritten(0),
mActiveTracksGeneration(0),
// mStreamTypes[] initialized in constructor body
mOutput(output),
@@ -2863,6 +2864,7 @@
// and associate with the sink frames written out. We need
// this to convert the sink timestamp to the track timestamp.
if (mNormalSink != 0) {
+ // Note: The DuplicatingThread may not have a mNormalSink.
// We always fetch the timestamp here because often the downstream
// sink will block whie writing.
ExtendedTimestamp timestamp; // use private copy to fetch
@@ -2872,23 +2874,20 @@
timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
-
- // sinkFramesWritten for non-offloaded tracks are contiguous
- // even after standby() is called. This is useful for the track frame
- // to sink frame mapping.
- const int64_t sinkFramesWritten = mNormalSink->framesWritten();
- mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = sinkFramesWritten;
- mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime();
-
- const size_t size = mActiveTracks.size();
- for (size_t i = 0; i < size; ++i) {
- sp<Track> t = mActiveTracks[i].promote();
- if (t != 0 && !t->isFastTrack()) {
- t->updateTrackFrameInfo(
- t->mAudioTrackServerProxy->framesReleased(),
- sinkFramesWritten,
- mTimestamp);
- }
+ }
+ // mFramesWritten for non-offloaded tracks are contiguous
+ // even after standby() is called. This is useful for the track frame
+ // to sink frame mapping.
+ mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = mFramesWritten;
+ mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime();
+ const size_t size = mActiveTracks.size();
+ for (size_t i = 0; i < size; ++i) {
+ sp<Track> t = mActiveTracks[i].promote();
+ if (t != 0 && !t->isFastTrack()) {
+ t->updateTrackFrameInfo(
+ t->mAudioTrackServerProxy->framesReleased(),
+ mFramesWritten,
+ mTimestamp);
}
}
@@ -3026,6 +3025,7 @@
mSleepTimeUs = suspendSleepTimeUs();
// simulate write to HAL when suspended
mBytesWritten += mSinkBufferSize;
+ mFramesWritten += mSinkBufferSize / mFrameSize;
mBytesRemaining = 0;
}
@@ -3076,6 +3076,7 @@
} else {
mBytesWritten += ret;
mBytesRemaining -= ret;
+ mFramesWritten += ret / mFrameSize;
}
} else if ((mMixerStatus == MIXER_DRAIN_TRACK) ||
(mMixerStatus == MIXER_DRAIN_ALL)) {
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 507f197..42b3266 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -693,6 +693,7 @@
volatile int32_t mSuspended;
int64_t mBytesWritten;
+ int64_t mFramesWritten; // not reset on standby
private:
// mMasterMute is in both PlaybackThread and in AudioFlinger. When a
// PlaybackThread needs to find out if master-muted, it checks it's local
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index a67693f..e684fc2 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -960,9 +960,17 @@
(long long)mPresentationCompleteFrames, audioHalFrames);
}
- if ((!isOffloaded() && !isDirect() && !isFastTrack()
- && framesWritten >= mPresentationCompleteFrames
- && mAudioTrackServerProxy->isDrained()) || isOffloaded()) {
+ bool complete;
+ if (isOffloaded()) {
+ complete = true;
+ } else if (isDirect() || isFastTrack()) { // these do not go through linear map
+ complete = framesWritten >= mPresentationCompleteFrames;
+ } else { // Normal tracks, OutputTracks, and PatchTracks
+ complete = framesWritten >= mPresentationCompleteFrames
+ && mAudioTrackServerProxy->isDrained();
+ }
+
+ if (complete) {
triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
mAudioTrackServerProxy->setStreamEndDone();
return true;