Merge changes I5d62a6c2,Iebf76958,I8068f0f7
* changes:
improve resample test
change how we store the FIR coefficients
improve SINC resampler performance
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 156c592..f9f6e8d 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -43,15 +43,15 @@
*/
enum event_type {
EVENT_MORE_DATA = 0, // Request to read more data from PCM buffer.
- EVENT_OVERRUN = 1, // PCM buffer overrun occured.
+ EVENT_OVERRUN = 1, // PCM buffer overrun occurred.
EVENT_MARKER = 2, // Record head is at the specified marker position
// (See setMarkerPosition()).
EVENT_NEW_POS = 3, // Record head is at a new position
// (See setPositionUpdatePeriod()).
};
- /* Create Buffer on the stack and pass it to obtainBuffer()
- * and releaseBuffer().
+ /* Client should declare Buffer on the stack and pass address to obtainBuffer()
+ * and releaseBuffer(). See also callback_t for EVENT_MORE_DATA.
*/
class Buffer
@@ -63,26 +63,30 @@
uint32_t flags;
int channelCount;
audio_format_t format;
- size_t frameCount;
+
+ size_t frameCount; // number of sample frames corresponding to size;
+ // on input it is the number of frames available,
+ // on output is the number of frames actually drained
+
size_t size; // total size in bytes == frameCount * frameSize
union {
void* raw;
- short* i16;
- int8_t* i8;
+ short* i16; // signed 16-bit
+ int8_t* i8; // unsigned 8-bit, offset by 0x80
};
};
/* As a convenience, if a callback is supplied, a handler thread
* is automatically created with the appropriate priority. This thread
- * invokes the callback when a new buffer becomes ready or an overrun condition occurs.
+ * invokes the callback when a new buffer becomes ready or various conditions occur.
* Parameters:
*
* event: type of event notified (see enum AudioRecord::event_type).
* user: Pointer to context for use by the callback receiver.
* info: Pointer to optional parameter according to event type:
* - EVENT_MORE_DATA: pointer to AudioRecord::Buffer struct. The callback must not read
- * more bytes than indicated by 'size' field and update 'size' if less bytes are
- * read.
+ * more bytes than indicated by 'size' field and update 'size' if fewer bytes are
+ * consumed.
* - EVENT_OVERRUN: unused.
* - EVENT_MARKER: pointer to const uint32_t containing the marker position in frames.
* - EVENT_NEW_POS: pointer to const uint32_t containing the new position in frames.
@@ -108,7 +112,7 @@
*/
AudioRecord();
- /* Creates an AudioRecord track and registers it with AudioFlinger.
+ /* Creates an AudioRecord object and registers it with AudioFlinger.
* Once created, the track needs to be started before it can be used.
* Unspecified values are set to the audio hardware's current
* values.
@@ -120,10 +124,13 @@
* format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
* 16 bits per sample).
* channelMask: Channel mask.
- * frameCount: Total size of track PCM buffer in frames. This defines the
- * latency of the track.
+ * frameCount: Minimum size of track PCM buffer in frames. This defines the
+ * application's contribution to the
+ * latency of the track. The actual size selected by the AudioRecord could
+ * be larger if the requested size is not compatible with current audio HAL
+ * latency. Zero means to use a default value.
* cbf: Callback function. If not null, this function is called periodically
- * to provide new PCM data.
+ * to consume new PCM data.
* user: Context for use by the callback receiver.
* notificationFrames: The callback function is called each time notificationFrames PCM
* frames are ready in record track output buffer.
@@ -154,7 +161,7 @@
* - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
* - NO_INIT: audio server or audio hardware not initialized
* - PERMISSION_DENIED: recording is not allowed for the requesting process
- * */
+ */
status_t set(audio_source_t inputSource = AUDIO_SOURCE_DEFAULT,
uint32_t sampleRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
@@ -168,14 +175,14 @@
/* Result of constructing the AudioRecord. This must be checked
- * before using any AudioRecord API (except for set()), using
+ * before using any AudioRecord API (except for set()), because using
* an uninitialized AudioRecord produces undefined results.
* See set() method above for possible return codes.
*/
status_t initCheck() const;
- /* Returns this track's latency in milliseconds.
- * This includes the latency due to AudioRecord buffer size
+ /* Returns this track's estimated latency in milliseconds.
+ * This includes the latency due to AudioRecord buffer size,
* and audio hardware driver.
*/
uint32_t latency() const;
@@ -191,7 +198,7 @@
/* After it's created the track is not active. Call start() to
* make it active. If set, the callback will start being called.
- * if event is not AudioSystem::SYNC_EVENT_NONE, the capture start will be delayed until
+ * If event is not AudioSystem::SYNC_EVENT_NONE, the capture start will be delayed until
* the specified event occurs on the specified trigger session.
*/
status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
@@ -199,12 +206,12 @@
/* Stop a track. If set, the callback will cease being called and
* obtainBuffer returns STOPPED. Note that obtainBuffer() still works
- * and will fill up buffers until the pool is exhausted.
+ * and will drain buffers until the pool is exhausted.
*/
void stop();
bool stopped() const;
- /* get sample rate for this record track
+ /* Get sample rate for this record track in Hz.
*/
uint32_t getSampleRate() const;
@@ -258,7 +265,7 @@
*/
status_t getPosition(uint32_t *position) const;
- /* returns a handle on the audio input used by this AudioRecord.
+ /* Returns a handle on the audio input used by this AudioRecord.
*
* Parameters:
* none.
@@ -268,7 +275,7 @@
*/
audio_io_handle_t getInput() const;
- /* returns the audio session ID associated with this AudioRecord.
+ /* Returns the audio session ID associated with this AudioRecord.
*
* Parameters:
* none.
@@ -278,22 +285,30 @@
*/
int getSessionId() const;
- /* obtains a buffer of "frameCount" frames. The buffer must be
- * filled entirely. If the track is stopped, obtainBuffer() returns
+ /* Obtains a buffer of "frameCount" frames. The buffer must be
+ * drained entirely, and then released with releaseBuffer().
+ * If the track is stopped, obtainBuffer() returns
* STOPPED instead of NO_ERROR as long as there are buffers available,
* at which point NO_MORE_BUFFERS is returned.
- * Buffers will be returned until the pool (buffercount())
+ * Buffers will be returned until the pool
* is exhausted, at which point obtainBuffer() will either block
* or return WOULD_BLOCK depending on the value of the "blocking"
* parameter.
+ *
+ * Interpretation of waitCount:
+ * +n limits wait time to n * WAIT_PERIOD_MS,
+ * -1 causes an (almost) infinite wait time,
+ * 0 non-blocking.
*/
enum {
- NO_MORE_BUFFERS = 0x80000001,
+ NO_MORE_BUFFERS = 0x80000001, // same name in AudioFlinger.h, ok to be different value
STOPPED = 1
};
status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount);
+
+ /* Release an emptied buffer of "frameCount" frames for AudioFlinger to re-fill. */
void releaseBuffer(Buffer* audioBuffer);
@@ -302,16 +317,16 @@
*/
ssize_t read(void* buffer, size_t size);
- /* Return the amount of input frames lost in the audio driver since the last call of this
+ /* Return the number of input frames lost in the audio driver since the last call of this
* function. Audio driver is expected to reset the value to 0 and restart counting upon
* returning the current value by this function call. Such loss typically occurs when the
* user space process is blocked longer than the capacity of audio driver buffers.
- * Unit: the number of input audio frames
+ * Units: the number of input audio frames.
*/
unsigned int getInputFramesLost() const;
private:
- /* copying audio tracks is not allowed */
+ /* copying audio record objects is not allowed */
AudioRecord(const AudioRecord& other);
AudioRecord& operator = (const AudioRecord& other);
@@ -355,7 +370,7 @@
bool mActive; // protected by mLock
// for client callback handler
- callback_t mCbf;
+ callback_t mCbf; // callback handler for events, or NULL
void* mUserData;
// for notification APIs
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 3d45503..76af2f8 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -167,18 +167,6 @@
int notificationFrames = 0,
int sessionId = 0);
- // DEPRECATED
- explicit AudioTrack( int streamType,
- uint32_t sampleRate = 0,
- int format = AUDIO_FORMAT_DEFAULT,
- int channelMask = 0,
- int frameCount = 0,
- uint32_t flags = (uint32_t) AUDIO_OUTPUT_FLAG_NONE,
- callback_t cbf = 0,
- void* user = 0,
- int notificationFrames = 0,
- int sessionId = 0);
-
/* Creates an audio track and registers it with AudioFlinger. With this constructor,
* the PCM data to be rendered by AudioTrack is passed in a shared memory buffer
* identified by the argument sharedBuffer. This prototype is for static buffer playback.
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index fe42afa..6a86a00 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -33,28 +33,15 @@
#define WAIT_PERIOD_MS 10
#define RESTORE_TIMEOUT_MS 5000 // Maximum waiting time for a track to be restored
-#define CBLK_UNDERRUN_MSK 0x0001
-#define CBLK_UNDERRUN_ON 0x0001 // underrun (out) or overrrun (in) indication
-#define CBLK_UNDERRUN_OFF 0x0000 // no underrun
-#define CBLK_DIRECTION_MSK 0x0002
-#define CBLK_DIRECTION_OUT 0x0002 // this cblk is for an AudioTrack
-#define CBLK_DIRECTION_IN 0x0000 // this cblk is for an AudioRecord
-#define CBLK_FORCEREADY_MSK 0x0004
-#define CBLK_FORCEREADY_ON 0x0004 // track is considered ready immediately by AudioFlinger
-#define CBLK_FORCEREADY_OFF 0x0000 // track is ready when buffer full
-#define CBLK_INVALID_MSK 0x0008
-#define CBLK_INVALID_ON 0x0008 // track buffer is invalidated by AudioFlinger:
-#define CBLK_INVALID_OFF 0x0000 // must be re-created
-#define CBLK_DISABLED_MSK 0x0010
-#define CBLK_DISABLED_ON 0x0010 // track disabled by AudioFlinger due to underrun:
-#define CBLK_DISABLED_OFF 0x0000 // must be re-started
-#define CBLK_RESTORING_MSK 0x0020
-#define CBLK_RESTORING_ON 0x0020 // track is being restored after invalidation
-#define CBLK_RESTORING_OFF 0x0000 // by AudioFlinger
-#define CBLK_RESTORED_MSK 0x0040
-#define CBLK_RESTORED_ON 0x0040 // track has been restored after invalidation
-#define CBLK_RESTORED_OFF 0x0040 // by AudioFlinger
-#define CBLK_FAST 0x0080 // AudioFlinger successfully created a fast track
+#define CBLK_UNDERRUN 0x01 // set: underrun (out) or overrrun (in), clear: no underrun or overrun
+#define CBLK_DIRECTION 0x02 // set: cblk is for an AudioTrack, clear: for AudioRecord
+#define CBLK_FORCEREADY 0x04 // set: track is considered ready immediately by AudioFlinger,
+ // clear: track is ready when buffer full
+#define CBLK_INVALID 0x08 // track buffer invalidated by AudioFlinger, need to re-create
+#define CBLK_DISABLED 0x10 // track disabled by AudioFlinger due to underrun, need to re-start
+#define CBLK_RESTORING 0x20 // track is being restored after invalidation by AudioFlinger
+#define CBLK_RESTORED 0x40 // track has been restored after invalidation by AudioFlinger
+#define CBLK_FAST 0x80 // AudioFlinger successfully created a fast track
// Important: do not add any virtual methods, including ~
struct audio_track_cblk_t
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
old mode 100755
new mode 100644
diff --git a/media/libeffects/preprocessing/Android.mk b/media/libeffects/preprocessing/Android.mk
old mode 100755
new mode 100644
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
old mode 100755
new mode 100644
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index bdbee0d..bd558fa 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -292,16 +292,16 @@
mActive = true;
cblk->lock.lock();
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ if (!(cblk->flags & CBLK_INVALID)) {
cblk->lock.unlock();
ALOGV("mAudioRecord->start()");
ret = mAudioRecord->start(event, triggerSession);
cblk->lock.lock();
if (ret == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
}
}
- if (cblk->flags & CBLK_INVALID_MSK) {
+ if (cblk->flags & CBLK_INVALID) {
ret = restoreRecord_l(cblk);
}
cblk->lock.unlock();
@@ -466,7 +466,7 @@
mCblkMemory = cblk;
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
- android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags);
+ android_atomic_and(~CBLK_DIRECTION, &mCblk->flags);
mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
return NO_ERROR;
@@ -499,7 +499,7 @@
cblk->lock.unlock();
return WOULD_BLOCK;
}
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ if (!(cblk->flags & CBLK_INVALID)) {
mLock.unlock();
result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
cblk->lock.unlock();
@@ -509,7 +509,7 @@
}
cblk->lock.lock();
}
- if (cblk->flags & CBLK_INVALID_MSK) {
+ if (cblk->flags & CBLK_INVALID) {
goto create_new_record;
}
if (CC_UNLIKELY(result != NO_ERROR)) {
@@ -522,7 +522,7 @@
result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
cblk->lock.lock();
if (result == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
create_new_record:
result = AudioRecord::restoreRecord_l(cblk);
}
@@ -739,7 +739,7 @@
// The value of active is stale, but we are almost sure to be active here because
// otherwise we would have exited when obtainBuffer returned STOPPED earlier.
ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
- if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
+ if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) {
mCbf(EVENT_OVERRUN, mUserData, NULL);
}
}
@@ -759,7 +759,7 @@
{
status_t result;
- if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
+ if (!(android_atomic_or(CBLK_RESTORING, &cblk->flags) & CBLK_RESTORING)) {
ALOGW("dead IAudioRecord, creating a new one");
// signal old cblk condition so that other threads waiting for available buffers stop
// waiting now
@@ -780,10 +780,10 @@
}
// signal old cblk condition for other threads waiting for restore completion
- android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
+ android_atomic_or(CBLK_RESTORED, &cblk->flags);
cblk->cv.broadcast();
} else {
- if (!(cblk->flags & CBLK_RESTORED_MSK)) {
+ if (!(cblk->flags & CBLK_RESTORED)) {
ALOGW("dead IAudioRecord, waiting for a new one to be created");
mLock.unlock();
result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index ffed161..523d844 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -120,28 +120,6 @@
0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId);
}
-// DEPRECATED
-AudioTrack::AudioTrack(
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelMask,
- int frameCount,
- uint32_t flags,
- callback_t cbf,
- void* user,
- int notificationFrames,
- int sessionId)
- : mStatus(NO_INIT),
- mIsTimed(false),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
-{
- mStatus = set((audio_stream_type_t)streamType, sampleRate, (audio_format_t)format,
- (audio_channel_mask_t) channelMask,
- frameCount, (audio_output_flags_t)flags, cbf, user, notificationFrames,
- 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId);
-}
-
AudioTrack::AudioTrack(
audio_stream_type_t streamType,
uint32_t sampleRate,
@@ -391,7 +369,7 @@
cblk->lock.lock();
cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
cblk->waitTimeMs = 0;
- android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags);
+ android_atomic_and(~CBLK_DISABLED, &cblk->flags);
if (t != 0) {
t->resume();
} else {
@@ -400,19 +378,21 @@
androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
}
- ALOGV("start %p before lock cblk %p", this, mCblk);
+ ALOGV("start %p before lock cblk %p", this, cblk);
status_t status = NO_ERROR;
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ if (!(cblk->flags & CBLK_INVALID)) {
cblk->lock.unlock();
ALOGV("mAudioTrack->start()");
status = mAudioTrack->start();
cblk->lock.lock();
if (status == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
}
}
- if (cblk->flags & CBLK_INVALID_MSK) {
- status = restoreTrack_l(cblk, true);
+ if (cblk->flags & CBLK_INVALID) {
+ audio_track_cblk_t* temp = cblk;
+ status = restoreTrack_l(temp, true);
+ cblk = temp;
}
cblk->lock.unlock();
if (status != NO_ERROR) {
@@ -686,12 +666,13 @@
if (!stopped_l()) return INVALID_OPERATION;
- Mutex::Autolock _l(mCblk->lock);
+ audio_track_cblk_t* cblk = mCblk;
+ Mutex::Autolock _l(cblk->lock);
- if (position > mCblk->user) return BAD_VALUE;
+ if (position > cblk->user) return BAD_VALUE;
- mCblk->server = position;
- android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags);
+ cblk->server = position;
+ android_atomic_or(CBLK_FORCEREADY, &cblk->flags);
return NO_ERROR;
}
@@ -713,7 +694,8 @@
flush_l();
- mCblk->stepUser(mCblk->frameCount);
+ audio_track_cblk_t* cblk = mCblk;
+ cblk->stepUser(cblk->frameCount);
return NO_ERROR;
}
@@ -896,50 +878,51 @@
ALOGE("AudioFlinger could not create track, status: %d", status);
return status;
}
- sp<IMemory> cblk = track->getCblk();
- if (cblk == 0) {
+ sp<IMemory> iMem = track->getCblk();
+ if (iMem == 0) {
ALOGE("Could not get control block");
return NO_INIT;
}
mAudioTrack = track;
- mCblkMemory = cblk;
- mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
- // old has the previous value of mCblk->flags before the "or" operation
- int32_t old = android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags);
+ mCblkMemory = iMem;
+ audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer());
+ mCblk = cblk;
+ // old has the previous value of cblk->flags before the "or" operation
+ int32_t old = android_atomic_or(CBLK_DIRECTION, &cblk->flags);
if (flags & AUDIO_OUTPUT_FLAG_FAST) {
if (old & CBLK_FAST) {
- ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", mCblk->frameCount);
+ ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", cblk->frameCount);
} else {
- ALOGV("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", mCblk->frameCount);
+ ALOGV("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", cblk->frameCount);
// once denied, do not request again if IAudioTrack is re-created
flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
mFlags = flags;
}
if (sharedBuffer == 0) {
- mNotificationFramesAct = mCblk->frameCount/2;
+ mNotificationFramesAct = cblk->frameCount/2;
}
}
if (sharedBuffer == 0) {
- mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+ cblk->buffers = (char*)cblk + sizeof(audio_track_cblk_t);
} else {
- mCblk->buffers = sharedBuffer->pointer();
+ cblk->buffers = sharedBuffer->pointer();
// Force buffer full condition as data is already present in shared memory
- mCblk->stepUser(mCblk->frameCount);
+ cblk->stepUser(cblk->frameCount);
}
- mCblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) |
+ cblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) |
uint16_t(mVolume[LEFT] * 0x1000));
- mCblk->setSendLevel(mSendLevel);
+ cblk->setSendLevel(mSendLevel);
mAudioTrack->attachAuxEffect(mAuxEffectId);
- mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
- mCblk->waitTimeMs = 0;
+ cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
+ cblk->waitTimeMs = 0;
mRemainingFrames = mNotificationFramesAct;
// FIXME don't believe this lie
- mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate;
+ mLatency = afLatency + (1000*cblk->frameCount) / sampleRate;
// If IAudioTrack is re-created, don't let the requested frameCount
// decrease. This can confuse clients that cache frameCount().
- if (mCblk->frameCount > mFrameCount) {
- mFrameCount = mCblk->frameCount;
+ if (cblk->frameCount > mFrameCount) {
+ mFrameCount = cblk->frameCount;
}
return NO_ERROR;
}
@@ -959,7 +942,7 @@
uint32_t framesAvail = cblk->framesAvailable();
cblk->lock.lock();
- if (cblk->flags & CBLK_INVALID_MSK) {
+ if (cblk->flags & CBLK_INVALID) {
goto create_new_track;
}
cblk->lock.unlock();
@@ -978,7 +961,7 @@
cblk->lock.unlock();
return WOULD_BLOCK;
}
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ if (!(cblk->flags & CBLK_INVALID)) {
mLock.unlock();
result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
cblk->lock.unlock();
@@ -989,7 +972,7 @@
cblk->lock.lock();
}
- if (cblk->flags & CBLK_INVALID_MSK) {
+ if (cblk->flags & CBLK_INVALID) {
goto create_new_track;
}
if (CC_UNLIKELY(result != NO_ERROR)) {
@@ -1005,9 +988,11 @@
result = mAudioTrack->start();
cblk->lock.lock();
if (result == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
create_new_track:
- result = restoreTrack_l(cblk, false);
+ audio_track_cblk_t* temp = cblk;
+ result = restoreTrack_l(temp, false);
+ cblk = temp;
}
if (result != NO_ERROR) {
ALOGW("obtainBuffer create Track error %d", result);
@@ -1060,12 +1045,13 @@
void AudioTrack::releaseBuffer(Buffer* audioBuffer)
{
AutoMutex lock(mLock);
- mCblk->stepUser(audioBuffer->frameCount);
+ audio_track_cblk_t* cblk = mCblk;
+ cblk->stepUser(audioBuffer->frameCount);
if (audioBuffer->frameCount > 0) {
// restart track if it was disabled by audioflinger due to previous underrun
- if (mActive && (mCblk->flags & CBLK_DISABLED_MSK)) {
- android_atomic_and(~CBLK_DISABLED_ON, &mCblk->flags);
- ALOGW("releaseBuffer() track %p name=%#x disabled, restarting", this, mCblk->mName);
+ if (mActive && (cblk->flags & CBLK_DISABLED)) {
+ android_atomic_and(~CBLK_DISABLED, &cblk->flags);
+ ALOGW("releaseBuffer() track %p name=%#x disabled, restarting", this, cblk->mName);
mAudioTrack->start();
}
}
@@ -1149,19 +1135,22 @@
// If the track is not invalid already, try to allocate a buffer. alloc
// fails indicating that the server is dead, flag the track as invalid so
// we can attempt to restore in just a bit.
- if (!(mCblk->flags & CBLK_INVALID_MSK)) {
+ audio_track_cblk_t* cblk = mCblk;
+ if (!(cblk->flags & CBLK_INVALID)) {
result = mAudioTrack->allocateTimedBuffer(size, buffer);
if (result == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &mCblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
}
}
// If the track is invalid at this point, attempt to restore it. and try the
// allocation one more time.
- if (mCblk->flags & CBLK_INVALID_MSK) {
- mCblk->lock.lock();
- result = restoreTrack_l(mCblk, false);
- mCblk->lock.unlock();
+ if (cblk->flags & CBLK_INVALID) {
+ cblk->lock.lock();
+ audio_track_cblk_t* temp = cblk;
+ result = restoreTrack_l(temp, false);
+ cblk = temp;
+ cblk->lock.unlock();
if (result == OK)
result = mAudioTrack->allocateTimedBuffer(size, buffer);
@@ -1176,10 +1165,11 @@
status_t status = mAudioTrack->queueTimedBuffer(buffer, pts);
{
AutoMutex lock(mLock);
+ audio_track_cblk_t* cblk = mCblk;
// restart track if it was disabled by audioflinger due to previous underrun
if (buffer->size() != 0 && status == NO_ERROR &&
- mActive && (mCblk->flags & CBLK_DISABLED_MSK)) {
- android_atomic_and(~CBLK_DISABLED_ON, &mCblk->flags);
+ mActive && (cblk->flags & CBLK_DISABLED)) {
+ android_atomic_and(~CBLK_DISABLED, &cblk->flags);
ALOGW("queueTimedBuffer() track %p disabled, restarting", this);
mAudioTrack->start();
}
@@ -1213,7 +1203,7 @@
// Manage underrun callback
if (active && (cblk->framesAvailable() == cblk->frameCount)) {
ALOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
- if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
+ if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) {
mCbf(EVENT_UNDERRUN, mUserData, 0);
if (cblk->server == cblk->frameCount) {
mCbf(EVENT_BUFFER_END, mUserData, 0);
@@ -1307,10 +1297,10 @@
}
audioBuffer.size = writtenSize;
- // NOTE: mCblk->frameSize is not equal to AudioTrack::frameSize() for
- // 8 bit PCM data: in this case, mCblk->frameSize is based on a sample size of
+ // NOTE: cblk->frameSize is not equal to AudioTrack::frameSize() for
+ // 8 bit PCM data: in this case, cblk->frameSize is based on a sample size of
// 16 bit.
- audioBuffer.frameCount = writtenSize/mCblk->frameSize;
+ audioBuffer.frameCount = writtenSize/cblk->frameSize;
frames -= audioBuffer.frameCount;
@@ -1326,14 +1316,17 @@
return true;
}
-// must be called with mLock and cblk.lock held. Callers must also hold strong references on
+// must be called with mLock and refCblk.lock held. Callers must also hold strong references on
// the IAudioTrack and IMemory in case they are recreated here.
-// If the IAudioTrack is successfully restored, the cblk pointer is updated
-status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart)
+// If the IAudioTrack is successfully restored, the refCblk pointer is updated
+// FIXME Don't depend on caller to hold strong references.
+status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& refCblk, bool fromStart)
{
status_t result;
- if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
+ audio_track_cblk_t* cblk = refCblk;
+ audio_track_cblk_t* newCblk = cblk;
+ if (!(android_atomic_or(CBLK_RESTORING, &cblk->flags) & CBLK_RESTORING)) {
ALOGW("dead IAudioTrack, creating a new one from %s TID %d",
fromStart ? "start()" : "obtainBuffer()", gettid());
@@ -1362,54 +1355,55 @@
uint32_t user = cblk->user;
uint32_t server = cblk->server;
// restore write index and set other indexes to reflect empty buffer status
- mCblk->user = user;
- mCblk->server = user;
- mCblk->userBase = user;
- mCblk->serverBase = user;
+ newCblk = mCblk;
+ newCblk->user = user;
+ newCblk->server = user;
+ newCblk->userBase = user;
+ newCblk->serverBase = user;
// restore loop: this is not guaranteed to succeed if new frame count is not
// compatible with loop length
setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount);
if (!fromStart) {
- mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+ newCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
// Make sure that a client relying on callback events indicating underrun or
// the actual amount of audio frames played (e.g SoundPool) receives them.
if (mSharedBuffer == 0) {
uint32_t frames = 0;
if (user > server) {
- frames = ((user - server) > mCblk->frameCount) ?
- mCblk->frameCount : (user - server);
- memset(mCblk->buffers, 0, frames * mCblk->frameSize);
+ frames = ((user - server) > newCblk->frameCount) ?
+ newCblk->frameCount : (user - server);
+ memset(newCblk->buffers, 0, frames * newCblk->frameSize);
}
// restart playback even if buffer is not completely filled.
- android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags);
- // stepUser() clears CBLK_UNDERRUN_ON flag enabling underrun callbacks to
+ android_atomic_or(CBLK_FORCEREADY, &newCblk->flags);
+ // stepUser() clears CBLK_UNDERRUN flag enabling underrun callbacks to
// the client
- mCblk->stepUser(frames);
+ newCblk->stepUser(frames);
}
}
if (mSharedBuffer != 0) {
- mCblk->stepUser(mCblk->frameCount);
+ newCblk->stepUser(newCblk->frameCount);
}
if (mActive) {
result = mAudioTrack->start();
ALOGW_IF(result != NO_ERROR, "restoreTrack_l() start() failed status %d", result);
}
if (fromStart && result == NO_ERROR) {
- mNewPosition = mCblk->server + mUpdatePeriod;
+ mNewPosition = newCblk->server + mUpdatePeriod;
}
}
if (result != NO_ERROR) {
- android_atomic_and(~CBLK_RESTORING_ON, &cblk->flags);
+ android_atomic_and(~CBLK_RESTORING, &cblk->flags);
ALOGW_IF(result != NO_ERROR, "restoreTrack_l() failed status %d", result);
}
mRestoreStatus = result;
// signal old cblk condition for other threads waiting for restore completion
- android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
+ android_atomic_or(CBLK_RESTORED, &cblk->flags);
cblk->cv.broadcast();
} else {
bool haveLogged = false;
for (;;) {
- if (cblk->flags & CBLK_RESTORED_MSK) {
+ if (cblk->flags & CBLK_RESTORED) {
ALOGW("dead IAudioTrack restored");
result = mRestoreStatus;
cblk->lock.unlock();
@@ -1431,13 +1425,13 @@
}
}
ALOGV("restoreTrack_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
- result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
+ result, mActive, newCblk, cblk, newCblk->flags, cblk->flags);
if (result == NO_ERROR) {
// from now on we switch to the newly created cblk
- cblk = mCblk;
+ refCblk = newCblk;
}
- cblk->lock.lock();
+ newCblk->lock.lock();
ALOGW_IF(result != NO_ERROR, "restoreTrack_l() error %d TID %d", result, gettid());
@@ -1451,15 +1445,16 @@
char buffer[SIZE];
String8 result;
+ audio_track_cblk_t* cblk = mCblk;
result.append(" AudioTrack::dump\n");
snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType,
mVolume[0], mVolume[1]);
result.append(buffer);
snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat,
- mChannelCount, mCblk->frameCount);
+ mChannelCount, cblk->frameCount);
result.append(buffer);
snprintf(buffer, 255, " sample rate(%d), status(%d), muted(%d)\n",
- (mCblk == 0) ? 0 : mCblk->sampleRate, mStatus, mMuted);
+ (cblk == 0) ? 0 : cblk->sampleRate, mStatus, mMuted);
result.append(buffer);
snprintf(buffer, 255, " active(%d), latency (%d)\n", mActive, mLatency);
result.append(buffer);
@@ -1534,7 +1529,7 @@
uint32_t u = user;
u += frameCount;
// Ensure that user is never ahead of server for AudioRecord
- if (flags & CBLK_DIRECTION_MSK) {
+ if (flags & CBLK_DIRECTION) {
// If stepServer() has been called once, switch to normal obtainBuffer() timeout period
if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) {
bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
@@ -1558,8 +1553,8 @@
user = u;
// Clear flow control error condition as new data has been written/read to/from buffer.
- if (flags & CBLK_UNDERRUN_MSK) {
- android_atomic_and(~CBLK_UNDERRUN_MSK, &flags);
+ if (flags & CBLK_UNDERRUN) {
+ android_atomic_and(~CBLK_UNDERRUN, &flags);
}
return u;
@@ -1578,7 +1573,7 @@
bool flushed = (s == user);
s += frameCount;
- if (flags & CBLK_DIRECTION_MSK) {
+ if (flags & CBLK_DIRECTION) {
// Mark that we have read the first buffer so that next time stepUser() is called
// we switch to normal obtainBuffer() timeout period
if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) {
@@ -1616,7 +1611,7 @@
server = s;
- if (!(flags & CBLK_INVALID_MSK)) {
+ if (!(flags & CBLK_INVALID)) {
cv.signal();
}
lock.unlock();
@@ -1639,7 +1634,7 @@
uint32_t u = user;
uint32_t s = server;
- if (flags & CBLK_DIRECTION_MSK) {
+ if (flags & CBLK_DIRECTION) {
uint32_t limit = (s < loopStart) ? s : loopStart;
return limit + frameCount - u;
} else {
@@ -1652,7 +1647,7 @@
uint32_t u = user;
uint32_t s = server;
- if (flags & CBLK_DIRECTION_MSK) {
+ if (flags & CBLK_DIRECTION) {
if (u < loopEnd) {
return u - s;
} else {
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
old mode 100755
new mode 100644
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
old mode 100755
new mode 100644
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
old mode 100755
new mode 100644
diff --git a/media/libstagefright/SkipCutBuffer.cpp b/media/libstagefright/SkipCutBuffer.cpp
old mode 100755
new mode 100644
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 35bd431..cb44114 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2167,7 +2167,7 @@
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> track = mTracks[i];
if (sessionId == track->sessionId() &&
- !(track->mCblk->flags & CBLK_INVALID_MSK)) {
+ !(track->mCblk->flags & CBLK_INVALID)) {
result |= TRACK_SESSION;
break;
}
@@ -2186,7 +2186,7 @@
for (size_t i = 0; i < mTracks.size(); i++) {
sp<Track> track = mTracks[i];
if (sessionId == track->sessionId() &&
- !(track->mCblk->flags & CBLK_INVALID_MSK)) {
+ !(track->mCblk->flags & CBLK_INVALID)) {
return AudioSystem::getStrategyForStream(track->streamType());
}
}
@@ -3032,7 +3032,7 @@
}
// indicate to client process that the track was disabled because of underrun;
// it will then automatically call start() when data is available
- android_atomic_or(CBLK_DISABLED_ON, &track->mCblk->flags);
+ android_atomic_or(CBLK_DISABLED, &track->mCblk->flags);
// remove from active list, but state remains ACTIVE [confusing but true]
isActive = false;
break;
@@ -3314,7 +3314,7 @@
tracksToRemove->add(track);
// indicate to client process that the track was disabled because of underrun;
// it will then automatically call start() when data is available
- android_atomic_or(CBLK_DISABLED_ON, &cblk->flags);
+ android_atomic_or(CBLK_DISABLED, &cblk->flags);
// If one track is not ready, mark the mixer also not ready if:
// - the mixer was ready during previous round OR
// - no other track is ready
@@ -3447,7 +3447,7 @@
for (size_t i = 0; i < size; i++) {
sp<Track> t = mTracks[i];
if (t->streamType() == streamType) {
- android_atomic_or(CBLK_INVALID_ON, &t->mCblk->flags);
+ android_atomic_or(CBLK_INVALID, &t->mCblk->flags);
t->mCblk->cv.signal();
}
}
@@ -4195,6 +4195,9 @@
// mChannelCount
// mChannelMask
{
+ // client == 0 implies sharedBuffer == 0
+ ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
+
ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),
sharedBuffer->size());
@@ -4206,33 +4209,11 @@
size += bufferSize;
}
- if (client != NULL) {
+ if (client != 0) {
mCblkMemory = client->heap()->allocate(size);
if (mCblkMemory != 0) {
mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
- if (mCblk != NULL) { // construct the shared structure in-place.
- new(mCblk) audio_track_cblk_t();
- // clear all buffers
- mCblk->frameCount = frameCount;
- mCblk->sampleRate = sampleRate;
-// uncomment the following lines to quickly test 32-bit wraparound
-// mCblk->user = 0xffff0000;
-// mCblk->server = 0xffff0000;
-// mCblk->userBase = 0xffff0000;
-// mCblk->serverBase = 0xffff0000;
- mChannelCount = channelCount;
- mChannelMask = channelMask;
- if (sharedBuffer == 0) {
- mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
- memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
- // Force underrun condition to avoid false underrun callback until first data is
- // written to buffer (other flags are cleared)
- mCblk->flags = CBLK_UNDERRUN_ON;
- } else {
- mBuffer = sharedBuffer->pointer();
- }
- mBufferEnd = (uint8_t *)mBuffer + bufferSize;
- }
+ // can't assume mCblk != NULL
} else {
ALOGE("not enough memory for AudioTrack size=%u", size);
client->heap()->dump("AudioTrack");
@@ -4240,23 +4221,31 @@
}
} else {
mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
- // construct the shared structure in-place.
+ // assume mCblk != NULL
+ }
+
+ // construct the shared structure in-place.
+ if (mCblk != NULL) {
new(mCblk) audio_track_cblk_t();
// clear all buffers
mCblk->frameCount = frameCount;
mCblk->sampleRate = sampleRate;
// uncomment the following lines to quickly test 32-bit wraparound
-// mCblk->user = 0xffff0000;
-// mCblk->server = 0xffff0000;
-// mCblk->userBase = 0xffff0000;
-// mCblk->serverBase = 0xffff0000;
+// mCblk->user = 0xffff0000;
+// mCblk->server = 0xffff0000;
+// mCblk->userBase = 0xffff0000;
+// mCblk->serverBase = 0xffff0000;
mChannelCount = channelCount;
mChannelMask = channelMask;
- mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
- memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
- // Force underrun condition to avoid false underrun callback until first data is
- // written to buffer (other flags are cleared)
- mCblk->flags = CBLK_UNDERRUN_ON;
+ if (sharedBuffer == 0) {
+ mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
+ memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+ // Force underrun condition to avoid false underrun callback until first data is
+ // written to buffer (other flags are cleared)
+ mCblk->flags = CBLK_UNDERRUN;
+ } else {
+ mBuffer = sharedBuffer->pointer();
+ }
mBufferEnd = (uint8_t *)mBuffer + bufferSize;
}
}
@@ -4600,9 +4589,9 @@
if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) return true;
if (framesReady() >= mCblk->frameCount ||
- (mCblk->flags & CBLK_FORCEREADY_MSK)) {
+ (mCblk->flags & CBLK_FORCEREADY)) {
mFillingUpStatus = FS_FILLED;
- android_atomic_and(~CBLK_FORCEREADY_MSK, &mCblk->flags);
+ android_atomic_and(~CBLK_FORCEREADY, &mCblk->flags);
return true;
}
return false;
@@ -4745,8 +4734,8 @@
TrackBase::reset();
// Force underrun condition to avoid false underrun callback until first data is
// written to buffer
- android_atomic_and(~CBLK_FORCEREADY_MSK, &mCblk->flags);
- android_atomic_or(CBLK_UNDERRUN_ON, &mCblk->flags);
+ android_atomic_and(~CBLK_FORCEREADY, &mCblk->flags);
+ android_atomic_or(CBLK_UNDERRUN, &mCblk->flags);
mFillingUpStatus = FS_FILLING;
mResetDone = true;
if (mState == FLUSHED) {
@@ -5495,7 +5484,7 @@
TrackBase::reset();
// Force overrun condition to avoid false overrun callback until first data is
// read from buffer
- android_atomic_or(CBLK_UNDERRUN_ON, &mCblk->flags);
+ android_atomic_or(CBLK_UNDERRUN, &mCblk->flags);
}
recordThread->mLock.unlock();
if (doStop) {
@@ -5540,7 +5529,7 @@
{
if (mCblk != NULL) {
- mCblk->flags |= CBLK_DIRECTION_OUT;
+ mCblk->flags |= CBLK_DIRECTION;
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
mOutBuffer.frameCount = 0;
playbackThread->mTracks.add(this);