Merge "Extract out audio DSP code to utility library"
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index cb3d833..b106042 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -75,15 +75,15 @@
size_t size;
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 availlable or an underrun condition occurs.
+ * invokes the callback when a new buffer becomes available or an underrun condition occurs.
* Parameters:
*
* event: type of event notified (see enum AudioTrack::event_type).
@@ -94,8 +94,8 @@
* written.
* - EVENT_UNDERRUN: unused.
* - EVENT_LOOP_END: pointer to an int indicating the number of loops remaining.
- * - EVENT_MARKER: pointer to an uin32_t containing the marker position in frames.
- * - EVENT_NEW_POS: pointer to an uin32_t containing the new position in frames.
+ * - EVENT_MARKER: pointer to an uint32_t containing the marker position in frames.
+ * - EVENT_NEW_POS: pointer to an uint32_t containing the new position in frames.
* - EVENT_BUFFER_END: unused.
*/
@@ -135,9 +135,10 @@
* flags: Reserved for future use.
* cbf: Callback function. If not null, this function is called periodically
* to request new PCM data.
+ * user: Context for use by the callback receiver.
* notificationFrames: The callback function is called each time notificationFrames PCM
- * frames have been comsumed from track input buffer.
- * user Context for use by the callback receiver.
+ * frames have been consumed from track input buffer.
+ * sessionId: Specific session ID, or zero to use default.
*/
AudioTrack( int streamType,
@@ -152,11 +153,11 @@
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
+ * 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.
- * PCM data must be present into memory before the AudioTrack is started.
- * The Write() and Flush() methods are not supported in this case.
- * It is recommented to pass a callback function to be notified of playback end by an
+ * PCM data must be present in memory before the AudioTrack is started.
+ * The write() and flush() methods are not supported in this case.
+ * It is recommended to pass a callback function to be notified of playback end by an
* EVENT_UNDERRUN event.
*/
@@ -172,15 +173,15 @@
int sessionId = 0);
/* Terminates the AudioTrack and unregisters it from AudioFlinger.
- * Also destroys all resources assotiated with the AudioTrack.
+ * Also destroys all resources associated with the AudioTrack.
*/
~AudioTrack();
/* Initialize an uninitialized AudioTrack.
* Returned status (from utils/Errors.h) can be:
- * - NO_ERROR: successful intialization
- * - INVALID_OPERATION: AudioTrack is already intitialized
+ * - NO_ERROR: successful initialization
+ * - INVALID_OPERATION: AudioTrack is already initialized
* - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
* - NO_INIT: audio server or audio hardware not initialized
* */
@@ -199,13 +200,13 @@
/* Result of constructing the AudioTrack. This must be checked
- * before using any AudioTrack API (except for set()), using
+ * before using any AudioTrack API (except for set()), because using
* an uninitialized AudioTrack produces undefined results.
* See set() method above for possible return codes.
*/
status_t initCheck() const;
- /* Returns this track's latency in milliseconds.
+ /* Returns this track's estimated latency in milliseconds.
* This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
* and audio hardware driver.
*/
@@ -233,8 +234,8 @@
void stop();
bool stopped() const;
- /* flush a stopped track. All pending buffers are discarded.
- * This function has no effect if the track is not stoped.
+ /* Flush a stopped track. All pending buffers are discarded.
+ * This function has no effect if the track is not stopped.
*/
void flush();
@@ -244,26 +245,25 @@
*/
void pause();
- /* mute or unmutes this track.
- * While mutted, the callback, if set, is still called.
+ /* Mute or unmute this track.
+ * While muted, the callback, if set, is still called.
*/
void mute(bool);
bool muted() const;
-
- /* set volume for this track, mostly used for games' sound effects
- * left and right volumes. Levels must be <= 1.0.
+ /* Set volume for this track, mostly used for games' sound effects
+ * left and right volumes. Levels must be >= 0.0 and <= 1.0.
*/
status_t setVolume(float left, float right);
void getVolume(float* left, float* right);
- /* set the send level for this track. An auxiliary effect should be attached
- * to the track with attachEffect(). Level must be <= 1.0.
+ /* Set the send level for this track. An auxiliary effect should be attached
+ * to the track with attachEffect(). Level must be >= 0.0 and <= 1.0.
*/
status_t setAuxEffectSendLevel(float level);
void getAuxEffectSendLevel(float* level);
- /* set sample rate for this track, mostly used for games' sound effects
+ /* Set sample rate for this track, mostly used for games' sound effects
*/
status_t setSampleRate(int sampleRate);
uint32_t getSampleRate();
@@ -274,8 +274,8 @@
*
* loopStart: loop start expressed as the number of PCM frames played since AudioTrack start.
* loopEnd: loop end expressed as the number of PCM frames played since AudioTrack start.
- * loopCount: number of loops to execute. Calling setLoop() with loopCount == 0 cancels any pending or
- * active loop. loopCount = -1 means infinite looping.
+ * loopCount: number of loops to execute. Calling setLoop() with loopCount == 0 cancels any
+ * pending or active loop. loopCount = -1 means infinite looping.
*
* For proper operation the following condition must be respected:
* (loopEnd-loopStart) <= framecount()
@@ -283,10 +283,9 @@
status_t setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount);
status_t getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount);
-
- /* Sets marker position. When playback reaches the number of frames specified, a callback with event
- * type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker notification
- * callback.
+ /* Sets marker position. When playback reaches the number of frames specified, a callback with
+ * event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker
+ * notification callback.
* If the AudioTrack has been opened with no callback function associated, the operation will fail.
*
* Parameters:
@@ -301,10 +300,10 @@
status_t getMarkerPosition(uint32_t *marker);
- /* Sets position update period. Every time the number of frames specified has been played,
- * a callback with event type EVENT_NEW_POS is called.
- * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
- * callback.
+ /* Sets position update period. Every time the number of frames specified has been played,
+ * a callback with event type EVENT_NEW_POS is called.
+ * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
+ * callback.
* If the AudioTrack has been opened with no callback function associated, the operation will fail.
*
* Parameters:
@@ -318,12 +317,11 @@
status_t setPositionUpdatePeriod(uint32_t updatePeriod);
status_t getPositionUpdatePeriod(uint32_t *updatePeriod);
-
/* Sets playback head position within AudioTrack buffer. The new position is specified
- * in number of frames.
+ * in number of frames.
* This method must be called with the AudioTrack in paused or stopped state.
- * Note that the actual position set is <position> modulo the AudioTrack buffer size in frames.
- * Therefore using this method makes sense only when playing a "static" audio buffer
+ * Note that the actual position set is <position> modulo the AudioTrack buffer size in frames.
+ * Therefore using this method makes sense only when playing a "static" audio buffer
* as opposed to streaming.
* The getPosition() method on the other hand returns the total number of frames played since
* playback start.
@@ -335,12 +333,12 @@
* Returned status (from utils/Errors.h) can be:
* - NO_ERROR: successful operation
* - INVALID_OPERATION: the AudioTrack is not stopped.
- * - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack buffer
+ * - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack buffer
*/
status_t setPosition(uint32_t position);
status_t getPosition(uint32_t *position);
- /* Forces AudioTrack buffer full condition. When playing a static buffer, this method avoids
+ /* Forces AudioTrack buffer full condition. When playing a static buffer, this method avoids
* rewriting the buffer before restarting playback after a stop.
* This method must be called with the AudioTrack in paused or stopped state.
*
@@ -350,7 +348,7 @@
*/
status_t reload();
- /* returns a handle on the audio output used by this AudioTrack.
+ /* Returns a handle on the audio output used by this AudioTrack.
*
* Parameters:
* none.
@@ -360,18 +358,17 @@
*/
audio_io_handle_t getOutput();
- /* returns the unique ID associated to this track.
+ /* Returns the unique session ID associated with this track.
*
* Parameters:
* none.
*
* Returned value:
- * AudioTrack ID.
+ * AudioTrack session ID.
*/
int getSessionId();
-
- /* Attach track auxiliary output to specified effect. Used effectId = 0
+ /* Attach track auxiliary output to specified effect. Use effectId = 0
* to detach track from effect.
*
* Parameters:
@@ -385,9 +382,9 @@
*/
status_t attachAuxEffect(int effectId);
- /* obtains a buffer of "frameCount" frames. The buffer must be
+ /* Obtains a buffer of "frameCount" frames. The buffer must be
* filled entirely. If the track is stopped, obtainBuffer() returns
- * STOPPED instead of NO_ERROR as long as there are buffers availlable,
+ * 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())
* is exhausted, at which point obtainBuffer() will either block
@@ -403,10 +400,9 @@
status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount);
void releaseBuffer(Buffer* audioBuffer);
-
/* As a convenience we provide a write() interface to the audio buffer.
* This is implemented on top of lockBuffer/unlockBuffer. For best
- * performance
+ * performance use callbacks. Return actual number of bytes written.
*
*/
ssize_t write(const void* buffer, size_t size);
diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h
index 47d530b..3fa2bf8 100644
--- a/include/media/IAudioTrack.h
+++ b/include/media/IAudioTrack.h
@@ -46,13 +46,13 @@
*/
virtual void stop() = 0;
- /* flush a stopped track. All pending buffers are discarded.
- * This function has no effect if the track is not stoped.
+ /* Flush a stopped track. All pending buffers are discarded.
+ * This function has no effect if the track is not stopped.
*/
virtual void flush() = 0;
- /* mute or unmutes this track.
- * While mutted, the callback, if set, is still called.
+ /* Mute or unmute this track.
+ * While muted, the callback, if set, is still called.
*/
virtual void mute(bool) = 0;
@@ -67,7 +67,7 @@
*/
virtual status_t attachAuxEffect(int effectId) = 0;
- /* get this tracks control block */
+ /* get this track's control block */
virtual sp<IMemory> getCblk() const = 0;
};
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 20abd51..046d5e9 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -59,8 +59,8 @@
// The data members are grouped so that members accessed frequently and in the same context
// are in the same line of data cache.
- Mutex lock;
- Condition cv;
+ Mutex lock; // sizeof(int)
+ Condition cv; // sizeof(int)
volatile uint32_t user;
volatile uint32_t server;
uint32_t userBase;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 7e55fbd..6868d99 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1,4 +1,4 @@
-/* //device/extlibs/pv/android/AudioTrack.cpp
+/* frameworks/base/media/libmedia/AudioTrack.cpp
**
** Copyright 2007, The Android Open Source Project
**
@@ -477,7 +477,7 @@
status_t AudioTrack::setVolume(float left, float right)
{
- if (left > 1.0f || right > 1.0f) {
+ if (left < 0.0f || left > 1.0f || right < 0.0f || right > 1.0f) {
return BAD_VALUE;
}
@@ -809,9 +809,7 @@
LOGE("Could not get control block");
return NO_INIT;
}
- mAudioTrack.clear();
mAudioTrack = track;
- mCblkMemory.clear();
mCblkMemory = cblk;
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags);
@@ -1322,7 +1320,7 @@
uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount)
{
- uint32_t u = this->user;
+ uint32_t u = user;
u += frameCount;
// Ensure that user is never ahead of server for AudioRecord
@@ -1331,16 +1329,16 @@
if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) {
bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
}
- } else if (u > this->server) {
- LOGW("stepServer occured after track reset");
- u = this->server;
+ } else if (u > server) {
+ LOGW("stepServer occurred after track reset");
+ u = server;
}
if (u >= userBase + this->frameCount) {
userBase += this->frameCount;
}
- this->user = u;
+ user = u;
// Clear flow control error condition as new data has been written/read to/from buffer.
if (flags & CBLK_UNDERRUN_MSK) {
@@ -1357,7 +1355,7 @@
return false;
}
- uint32_t s = this->server;
+ uint32_t s = server;
s += frameCount;
if (flags & CBLK_DIRECTION_MSK) {
@@ -1370,9 +1368,9 @@
// while the mixer is processing a block: in this case,
// stepServer() is called After the flush() has reset u & s and
// we have s > u
- if (s > this->user) {
- LOGW("stepServer occured after track reset");
- s = this->user;
+ if (s > user) {
+ LOGW("stepServer occurred after track reset");
+ s = user;
}
}
@@ -1388,7 +1386,7 @@
serverBase += this->frameCount;
}
- this->server = s;
+ server = s;
if (!(flags & CBLK_INVALID_MSK)) {
cv.signal();
@@ -1399,7 +1397,7 @@
void* audio_track_cblk_t::buffer(uint32_t offset) const
{
- return (int8_t *)this->buffers + (offset - userBase) * this->frameSize;
+ return (int8_t *)buffers + (offset - userBase) * frameSize;
}
uint32_t audio_track_cblk_t::framesAvailable()
@@ -1410,8 +1408,8 @@
uint32_t audio_track_cblk_t::framesAvailable_l()
{
- uint32_t u = this->user;
- uint32_t s = this->server;
+ uint32_t u = user;
+ uint32_t s = server;
if (flags & CBLK_DIRECTION_MSK) {
uint32_t limit = (s < loopStart) ? s : loopStart;
@@ -1423,8 +1421,8 @@
uint32_t audio_track_cblk_t::framesReady()
{
- uint32_t u = this->user;
- uint32_t s = this->server;
+ uint32_t u = user;
+ uint32_t s = server;
if (flags & CBLK_DIRECTION_MSK) {
if (u < loopEnd) {
@@ -1469,4 +1467,3 @@
// -------------------------------------------------------------------------
}; // namespace android
-
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index d0d9ca6..3539e3f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -376,7 +376,7 @@
bool tooLate = (mVideoLateByUs > 40000);
if (tooLate) {
- ALOGV("video late by %lld us (%.2f secs)", lateByUs, lateByUs / 1E6);
+ ALOGV("video late by %lld us (%.2f secs)", mVideoLateByUs, mVideoLateByUs / 1E6);
} else {
ALOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
}
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index e72adc4..6d28298 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -38,7 +38,8 @@
mFlags(0),
mState(DISCONNECTED),
mFinalResult(OK),
- mDisconnectReplyID(0) {
+ mDisconnectReplyID(0),
+ mSeekGeneration(0) {
if (headers) {
mExtraHeaders = *headers;
@@ -146,14 +147,21 @@
}
status_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
+ sp<AMessage> msg = new AMessage(kWhatPerformSeek, mReflector->id());
+ msg->setInt32("generation", ++mSeekGeneration);
+ msg->setInt64("timeUs", seekTimeUs);
+ msg->post(200000ll);
+
+ return OK;
+}
+
+void NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
if (mState != CONNECTED) {
- return UNKNOWN_ERROR;
+ return;
}
mState = SEEKING;
mHandler->seek(seekTimeUs);
-
- return OK;
}
bool NuPlayer::RTSPSource::isSeekable() {
@@ -168,6 +176,20 @@
mDisconnectReplyID = replyID;
finishDisconnectIfPossible();
return;
+ } else if (msg->what() == kWhatPerformSeek) {
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+
+ if (generation != mSeekGeneration) {
+ // obsolete.
+ return;
+ }
+
+ int64_t seekTimeUs;
+ CHECK(msg->findInt64("timeUs", &seekTimeUs));
+
+ performSeek(seekTimeUs);
+ return;
}
CHECK_EQ(msg->what(), (int)kWhatNotify);
@@ -208,21 +230,32 @@
break;
}
- const TrackInfo &info = mTracks.editItemAt(trackIndex);
- sp<AnotherPacketSource> source = info.mSource;
+ TrackInfo *info = &mTracks.editItemAt(trackIndex);
+
+ sp<AnotherPacketSource> source = info->mSource;
if (source != NULL) {
-#if 1
uint32_t rtpTime;
CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
+ if (!info->mNPTMappingValid) {
+ // This is a live stream, we didn't receive any normal
+ // playtime mapping. Assume the first packets correspond
+ // to time 0.
+
+ ALOGV("This is a live stream, assuming time = 0");
+
+ info->mRTPTime = rtpTime;
+ info->mNormalPlaytimeUs = 0ll;
+ info->mNPTMappingValid = true;
+ }
+
int64_t nptUs =
- ((double)rtpTime - (double)info.mRTPTime)
- / info.mTimeScale
+ ((double)rtpTime - (double)info->mRTPTime)
+ / info->mTimeScale
* 1000000ll
- + info.mNormalPlaytimeUs;
+ + info->mNormalPlaytimeUs;
accessUnit->meta()->setInt64("timeUs", nptUs);
-#endif
source->queueAccessUnit(accessUnit);
}
@@ -278,6 +311,7 @@
TrackInfo *info = &mTracks.editItemAt(trackIndex);
info->mRTPTime = rtpTime;
info->mNormalPlaytimeUs = nptUs;
+ info->mNPTMappingValid = true;
break;
}
@@ -305,6 +339,7 @@
info.mTimeScale = timeScale;
info.mRTPTime = 0;
info.mNormalPlaytimeUs = 0ll;
+ info.mNPTMappingValid = false;
if ((isAudio && mAudioTrack == NULL)
|| (isVideo && mVideoTrack == NULL)) {
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h
index 66eab72..59d06ad 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h
@@ -56,6 +56,7 @@
enum {
kWhatNotify = 'noti',
kWhatDisconnect = 'disc',
+ kWhatPerformSeek = 'seek',
};
enum State {
@@ -76,6 +77,7 @@
int32_t mTimeScale;
uint32_t mRTPTime;
int64_t mNormalPlaytimeUs;
+ bool mNPTMappingValid;
};
AString mURL;
@@ -95,12 +97,16 @@
sp<AnotherPacketSource> mAudioTrack;
sp<AnotherPacketSource> mVideoTrack;
+ int32_t mSeekGeneration;
+
sp<AnotherPacketSource> getSource(bool audio);
void onConnected();
void onDisconnected(const sp<AMessage> &msg);
void finishDisconnectIfPossible();
+ void performSeek(int64_t seekTimeUs);
+
DISALLOW_EVIL_CONSTRUCTORS(RTSPSource);
};
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 51a7541..2f807d0 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -338,7 +338,9 @@
(uint32_t(buffer->height) != h) ||
(uint32_t(buffer->format) != format) ||
((uint32_t(buffer->usage) & usage) != usage)) {
- usage |= GraphicBuffer::USAGE_HW_VIDEO_ENCODER;
+ // XXX: This will be changed to USAGE_HW_VIDEO_ENCODER once driver
+ // issues with that flag get fixed.
+ usage |= GraphicBuffer::USAGE_HW_TEXTURE;
status_t error;
sp<GraphicBuffer> graphicBuffer(
mGraphicBufferAlloc->createGraphicBuffer(
diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/libstagefright/foundation/ABitReader.cpp
index f07dd4f..5499c32 100644
--- a/media/libstagefright/foundation/ABitReader.cpp
+++ b/media/libstagefright/foundation/ABitReader.cpp
@@ -79,7 +79,13 @@
}
void ABitReader::putBits(uint32_t x, size_t n) {
- CHECK_LE(mNumBitsLeft + n, 32u);
+ CHECK_LE(n, 32u);
+
+ while (mNumBitsLeft + n > 32) {
+ mNumBitsLeft -= 8;
+ --mData;
+ ++mSize;
+ }
mReservoir = (mReservoir >> n) | (x << (32 - n));
mNumBitsLeft += n;
diff --git a/media/libstagefright/rtsp/AAMRAssembler.cpp b/media/libstagefright/rtsp/AAMRAssembler.cpp
index 547b202..9d72b1f 100644
--- a/media/libstagefright/rtsp/AAMRAssembler.cpp
+++ b/media/libstagefright/rtsp/AAMRAssembler.cpp
@@ -79,13 +79,17 @@
}
static size_t getFrameSize(bool isWide, unsigned FT) {
- static const size_t kFrameSizeNB[8] = {
- 95, 103, 118, 134, 148, 159, 204, 244
+ static const size_t kFrameSizeNB[9] = {
+ 95, 103, 118, 134, 148, 159, 204, 244, 39
};
- static const size_t kFrameSizeWB[9] = {
- 132, 177, 253, 285, 317, 365, 397, 461, 477
+ static const size_t kFrameSizeWB[10] = {
+ 132, 177, 253, 285, 317, 365, 397, 461, 477, 40
};
+ if (FT == 15) {
+ return 1;
+ }
+
size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT];
// Round up bits to bytes and add 1 for the header byte.
@@ -161,8 +165,8 @@
unsigned FT = (toc >> 3) & 0x0f;
if ((toc & 3) != 0
- || (mIsWide && FT > 8)
- || (!mIsWide && FT > 7)) {
+ || (mIsWide && FT > 9 && FT != 15)
+ || (!mIsWide && FT > 8 && FT != 15)) {
queue->erase(queue->begin());
++mNextExpectedSeqNo;
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 0fbbb9e..d8107bc 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -659,6 +659,7 @@
}
AString line;
+ ssize_t lastDictIndex = -1;
for (;;) {
if (!receiveLine(&line)) {
break;
@@ -668,7 +669,21 @@
break;
}
- ALOGV("line: %s", line.c_str());
+ ALOGV("line: '%s'", line.c_str());
+
+ if (line.c_str()[0] == ' ' || line.c_str()[0] == '\t') {
+ // Support for folded header values.
+
+ if (lastDictIndex < 0) {
+ // First line cannot be a continuation of the previous one.
+ return false;
+ }
+
+ AString &value = response->mHeaders.editValueAt(lastDictIndex);
+ value.append(line);
+
+ continue;
+ }
ssize_t colonPos = line.find(":");
if (colonPos < 0) {
@@ -681,9 +696,12 @@
key.tolower();
line.erase(0, colonPos + 1);
- line.trim();
- response->mHeaders.add(key, line);
+ lastDictIndex = response->mHeaders.add(key, line);
+ }
+
+ for (size_t i = 0; i < response->mHeaders.size(); ++i) {
+ response->mHeaders.editValueAt(i).trim();
}
unsigned long contentLength = 0;
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index dd049c2..21ef298 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -1100,6 +1100,8 @@
float npt1, npt2;
if (!ASessionDescription::parseNTPRange(val.c_str(), &npt1, &npt2)) {
// This is a live stream and therefore not seekable.
+
+ LOGI("This is a live stream");
return;
}
@@ -1386,12 +1388,14 @@
msg->setInt32("what", kWhatConnected);
msg->post();
- for (size_t i = 0; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
+ if (mSeekable) {
+ for (size_t i = 0; i < mTracks.size(); ++i) {
+ TrackInfo *info = &mTracks.editItemAt(i);
- postNormalPlayTimeMapping(
- i,
- info->mNormalPlayTimeRTP, info->mNormalPlayTimeUs);
+ postNormalPlayTimeMapping(
+ i,
+ info->mNormalPlayTimeRTP, info->mNormalPlayTimeUs);
+ }
}
mFirstAccessUnit = false;
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 7094cfa..b5f85f9 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -15,11 +15,6 @@
** limitations under the License.
*/
-// System headers required for setgroups, etc.
-#include <sys/types.h>
-#include <unistd.h>
-#include <grp.h>
-
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
@@ -29,7 +24,6 @@
#include <CameraService.h>
#include <MediaPlayerService.h>
#include <AudioPolicyService.h>
-#include <private/android_filesystem_config.h>
using namespace android;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 58482d5..849898c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -65,8 +65,8 @@
namespace android {
-static const char* kDeadlockedString = "AudioFlinger may be deadlocked\n";
-static const char* kHardwareLockedString = "Hardware lock is taken\n";
+static const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
+static const char kHardwareLockedString[] = "Hardware lock is taken\n";
//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
static const float MAX_GAIN = 4096.0f;
@@ -82,14 +82,16 @@
static const int8_t kMaxTrackRetriesDirect = 2;
static const int kDumpLockRetries = 50;
-static const int kDumpLockSleep = 20000;
+static const int kDumpLockSleepUs = 20000;
-static const nsecs_t kWarningThrottle = seconds(5);
+// don't warn about blocked writes or record buffer overflows more often than this
+static const nsecs_t kWarningThrottleNs = seconds(5);
// RecordThread loop sleep time upon application overrun or audio HAL read error
static const int kRecordThreadSleepUs = 5000;
-static const nsecs_t kSetParametersTimeout = seconds(2);
+// maximum time to wait for setParameters to complete
+static const nsecs_t kSetParametersTimeoutNs = seconds(2);
// minimum sleep time for the mixer thread loop when tracks are active but in underrun
static const uint32_t kMinThreadSleepTimeUs = 5000;
@@ -149,7 +151,7 @@
return rc;
}
-static const char *audio_interfaces[] = {
+static const char * const audio_interfaces[] = {
"primary",
"a2dp",
"usb",
@@ -160,7 +162,7 @@
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
- mPrimaryHardwareDev(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1),
+ mPrimaryHardwareDev(NULL), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1),
mBtNrecIsOff(false)
{
}
@@ -322,7 +324,7 @@
locked = true;
break;
}
- usleep(kDumpLockSleep);
+ usleep(kDumpLockSleepUs);
}
return locked;
}
@@ -397,7 +399,7 @@
int lSessionId;
if (streamType >= AUDIO_STREAM_CNT) {
- LOGE("invalid stream type");
+ LOGE("createTrack() invalid stream type %d", streamType);
lStatus = BAD_VALUE;
goto Exit;
}
@@ -429,6 +431,7 @@
// prevent same audio session on different output threads
uint32_t sessions = t->hasAudioSession(*sessionId);
if (sessions & PlaybackThread::TRACK_SESSION) {
+ LOGE("createTrack() session ID %d already in use", *sessionId);
lStatus = BAD_VALUE;
goto Exit;
}
@@ -659,6 +662,7 @@
}
if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ LOGE("setStreamVolume() invalid stream %d", stream);
return BAD_VALUE;
}
@@ -693,6 +697,7 @@
if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT ||
uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {
+ LOGE("setStreamMute() invalid stream %d", stream);
return BAD_VALUE;
}
@@ -990,7 +995,6 @@
AudioFlinger::ThreadBase::~ThreadBase()
{
mParamCond.broadcast();
- mNewParameters.clear();
// do not lock the mutex in destructor
releaseWakeLock_l();
if (mPowerManager != 0) {
@@ -1001,7 +1005,7 @@
void AudioFlinger::ThreadBase::exit()
{
- // keep a strong ref on ourself so that we wont get
+ // keep a strong ref on ourself so that we won't get
// destroyed in the middle of requestExitAndWait()
sp <ThreadBase> strongMe = this;
@@ -1046,7 +1050,7 @@
mWaitWorkCV.signal();
// wait condition with timeout in case the thread loop has exited
// before the request could be processed
- if (mParamCond.waitRelative(mLock, kSetParametersTimeout) == NO_ERROR) {
+ if (mParamCond.waitRelative(mLock, kSetParametersTimeoutNs) == NO_ERROR) {
status = mParamStatus;
mWaitWorkCV.signal();
} else {
@@ -1064,9 +1068,9 @@
// sendConfigEvent_l() must be called with ThreadBase::mLock held
void AudioFlinger::ThreadBase::sendConfigEvent_l(int event, int param)
{
- ConfigEvent *configEvent = new ConfigEvent();
- configEvent->mEvent = event;
- configEvent->mParam = param;
+ ConfigEvent configEvent;
+ configEvent.mEvent = event;
+ configEvent.mParam = param;
mConfigEvents.add(configEvent);
ALOGV("sendConfigEvent() num events %d event %d, param %d", mConfigEvents.size(), event, param);
mWaitWorkCV.signal();
@@ -1077,15 +1081,14 @@
mLock.lock();
while(!mConfigEvents.isEmpty()) {
ALOGV("processConfigEvents() remaining events %d", mConfigEvents.size());
- ConfigEvent *configEvent = mConfigEvents[0];
+ ConfigEvent configEvent = mConfigEvents[0];
mConfigEvents.removeAt(0);
// release mLock before locking AudioFlinger mLock: lock order is always
// AudioFlinger then ThreadBase to avoid cross deadlock
mLock.unlock();
mAudioFlinger->mLock.lock();
- audioConfigChanged_l(configEvent->mEvent, configEvent->mParam);
+ audioConfigChanged_l(configEvent.mEvent, configEvent.mParam);
mAudioFlinger->mLock.unlock();
- delete configEvent;
mLock.lock();
}
mLock.unlock();
@@ -1132,7 +1135,7 @@
snprintf(buffer, SIZE, " Index event param\n");
result.append(buffer);
for (size_t i = 0; i < mConfigEvents.size(); i++) {
- snprintf(buffer, SIZE, " %02d %02d %d\n", i, mConfigEvents[i]->mEvent, mConfigEvents[i]->mParam);
+ snprintf(buffer, SIZE, " %02d %02d %d\n", i, mConfigEvents[i].mEvent, mConfigEvents[i].mParam);
result.append(buffer);
}
result.append("\n");
@@ -1369,7 +1372,7 @@
int id,
uint32_t device)
: ThreadBase(audioFlinger, id, device),
- mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
+ mMixBuffer(NULL), mSuspended(0), mBytesWritten(0), mOutput(output),
mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
{
snprintf(mName, kNameLength, "AudioOut_%d", id);
@@ -1528,8 +1531,10 @@
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> t = mTracks[i];
if (t != 0) {
- if (sessionId == t->sessionId() &&
- strategy != AudioSystem::getStrategyForStream((audio_stream_type_t)t->type())) {
+ uint32_t actual = AudioSystem::getStrategyForStream((audio_stream_type_t)t->type());
+ if (sessionId == t->sessionId() && strategy != actual) {
+ LOGE("createTrack_l() mismatched strategy; expected %u but found %u",
+ strategy, actual);
lStatus = BAD_VALUE;
goto Exit;
}
@@ -1834,7 +1839,7 @@
AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
: PlaybackThread(audioFlinger, output, id, device),
- mAudioMixer(0)
+ mAudioMixer(NULL)
{
mType = ThreadBase::MIXER;
mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
@@ -1969,7 +1974,7 @@
// during mixing and effect process as the audio buffers could be deleted
// or modified if an effect is created or deleted
lockEffectChains_l(effectChains);
- }
+ }
if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
// mix buffers...
@@ -2014,11 +2019,11 @@
}
// sleepTime == 0 means we must write to audio hardware
if (sleepTime == 0) {
- for (size_t i = 0; i < effectChains.size(); i ++) {
- effectChains[i]->process_l();
- }
- // enable changes in effect chain
- unlockEffectChains(effectChains);
+ for (size_t i = 0; i < effectChains.size(); i ++) {
+ effectChains[i]->process_l();
+ }
+ // enable changes in effect chain
+ unlockEffectChains(effectChains);
mLastWriteTime = systemTime();
mInWrite = true;
mBytesWritten += mixBufferSize;
@@ -2031,7 +2036,7 @@
nsecs_t delta = now - mLastWriteTime;
if (!mStandby && delta > maxPeriod) {
mNumDelayedWrites++;
- if ((now - lastWarning) > kWarningThrottle) {
+ if ((now - lastWarning) > kWarningThrottleNs) {
LOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
ns2ms(delta), mNumDelayedWrites, this);
lastWarning = now;
@@ -2199,7 +2204,7 @@
// XXX: these things DON'T need to be done each time
mAudioMixer->setBufferProvider(track);
- mAudioMixer->enable(AudioMixer::MIXING);
+ mAudioMixer->enable();
mAudioMixer->setParameter(param, AudioMixer::VOLUME0, (void *)left);
mAudioMixer->setParameter(param, AudioMixer::VOLUME1, (void *)right);
@@ -2245,7 +2250,7 @@
mixerStatus = MIXER_TRACKS_ENABLED;
}
}
- mAudioMixer->disable(AudioMixer::MIXING);
+ mAudioMixer->disable();
}
}
@@ -2346,7 +2351,7 @@
}
if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
// do not accept frame count changes if tracks are open as the track buffer
- // size depends on frame count and correct behavior would not be garantied
+ // size depends on frame count and correct behavior would not be guaranteed
// if frame count is changed after track creation
if (!mTracks.isEmpty()) {
status = INVALID_OPERATION;
@@ -2417,7 +2422,7 @@
mParamCond.signal();
// wait for condition with time out in case the thread calling ThreadBase::setParameters()
// already timed out waiting for the status and will never signal the condition.
- mWaitWorkCV.waitRelative(mLock, kSetParametersTimeout);
+ mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs);
}
return reconfig;
}
@@ -2760,7 +2765,7 @@
while (frameCount) {
buffer.frameCount = frameCount;
activeTrack->getNextBuffer(&buffer);
- if (UNLIKELY(buffer.raw == 0)) {
+ if (UNLIKELY(buffer.raw == NULL)) {
memset(curBuf, 0, frameCount * mFrameSize);
break;
}
@@ -2885,7 +2890,7 @@
mParamCond.signal();
// wait for condition with time out in case the thread calling ThreadBase::setParameters()
// already timed out waiting for the status and will never signal the condition.
- mWaitWorkCV.waitRelative(mLock, kSetParametersTimeout);
+ mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs);
}
return reconfig;
}
@@ -3258,7 +3263,7 @@
void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
{
- buffer->raw = 0;
+ buffer->raw = NULL;
mFrameCount = buffer->frameCount;
step();
buffer->frameCount = 0;
@@ -3451,14 +3456,14 @@
}
buffer->raw = getBuffer(s, framesReq);
- if (buffer->raw == 0) goto getNextBuffer_exit;
+ if (buffer->raw == NULL) goto getNextBuffer_exit;
buffer->frameCount = framesReq;
return NO_ERROR;
}
getNextBuffer_exit:
- buffer->raw = 0;
+ buffer->raw = NULL;
buffer->frameCount = 0;
ALOGV("getNextBuffer() no more data for track %d on thread %p", mName, mThread.unsafe_get());
return NOT_ENOUGH_DATA;
@@ -3699,14 +3704,14 @@
}
buffer->raw = getBuffer(s, framesReq);
- if (buffer->raw == 0) goto getNextBuffer_exit;
+ if (buffer->raw == NULL) goto getNextBuffer_exit;
buffer->frameCount = framesReq;
return NO_ERROR;
}
getNextBuffer_exit:
- buffer->raw = 0;
+ buffer->raw = NULL;
buffer->frameCount = 0;
return NOT_ENOUGH_DATA;
}
@@ -4211,7 +4216,7 @@
int id,
uint32_t device) :
ThreadBase(audioFlinger, id, device),
- mInput(input), mTrack(NULL), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
+ mInput(input), mTrack(NULL), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL)
{
mType = ThreadBase::RECORD;
@@ -4226,7 +4231,7 @@
AudioFlinger::RecordThread::~RecordThread()
{
delete[] mRsmpInBuffer;
- if (mResampler != 0) {
+ if (mResampler != NULL) {
delete mResampler;
delete[] mRsmpOutBuffer;
}
@@ -4320,7 +4325,7 @@
buffer.frameCount = mFrameCount;
if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
size_t framesOut = buffer.frameCount;
- if (mResampler == 0) {
+ if (mResampler == NULL) {
// no resampling
while (framesOut) {
size_t framesIn = mFrameCount - mRsmpInIndex;
@@ -4405,7 +4410,7 @@
else {
if (!mActiveTrack->setOverflow()) {
nsecs_t now = systemTime();
- if ((now - lastWarning) > kWarningThrottle) {
+ if ((now - lastWarning) > kWarningThrottleNs) {
LOGW("RecordThread: buffer overflow");
lastWarning = now;
}
@@ -4578,7 +4583,7 @@
result.append(buffer);
snprintf(buffer, SIZE, "In size: %d\n", mInputBytes);
result.append(buffer);
- snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != 0));
+ snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != NULL));
result.append(buffer);
snprintf(buffer, SIZE, "Out channel count: %d\n", mReqChannelCount);
result.append(buffer);
@@ -4613,7 +4618,7 @@
mInput->stream->common.standby(&mInput->stream->common);
usleep(kRecordThreadSleepUs);
}
- buffer->raw = 0;
+ buffer->raw = NULL;
buffer->frameCount = 0;
return NOT_ENOUGH_DATA;
}
@@ -4728,7 +4733,7 @@
mParamCond.signal();
// wait for condition with time out in case the thread calling ThreadBase::setParameters()
// already timed out waiting for the status and will never signal the condition.
- mWaitWorkCV.waitRelative(mLock, kSetParametersTimeout);
+ mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs);
}
return reconfig;
}
@@ -4776,7 +4781,7 @@
if (mRsmpInBuffer) delete mRsmpInBuffer;
if (mRsmpOutBuffer) delete mRsmpOutBuffer;
if (mResampler) delete mResampler;
- mResampler = 0;
+ mResampler = NULL;
mSampleRate = mInput->stream->common.get_sample_rate(&mInput->stream->common);
mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 6cafa7e..9707cf4 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -547,7 +547,7 @@
Condition mParamCond;
Vector<String8> mNewParameters;
status_t mParamStatus;
- Vector<ConfigEvent *> mConfigEvents;
+ Vector<ConfigEvent> mConfigEvents;
bool mStandby;
int mId;
bool mExiting;
@@ -703,7 +703,7 @@
virtual status_t readyToRun();
virtual void onFirstRef();
- virtual status_t initCheck() const { return (mOutput == 0) ? NO_INIT : NO_ERROR; }
+ virtual status_t initCheck() const { return (mOutput == NULL) ? NO_INIT : NO_ERROR; }
virtual uint32_t latency() const;
@@ -980,7 +980,7 @@
virtual status_t readyToRun();
virtual void onFirstRef();
- virtual status_t initCheck() const { return (mInput == 0) ? NO_INIT : NO_ERROR; }
+ virtual status_t initCheck() const { return (mInput == NULL) ? NO_INIT : NO_ERROR; }
sp<AudioFlinger::RecordThread::RecordTrack> createRecordTrack_l(
const sp<AudioFlinger::Client>& client,
uint32_t sampleRate,
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index fe56771..c571619 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "AudioMixer"
//#define LOG_NDEBUG 0
+#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
@@ -41,50 +42,58 @@
AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
: mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate)
{
+ // AudioMixer is not yet capable of multi-channel beyond stereo
+ assert(2 == MAX_NUM_CHANNELS);
mState.enabledTracks= 0;
mState.needsChanged = 0;
mState.frameCount = frameCount;
- mState.outputTemp = 0;
- mState.resampleTemp = 0;
+ mState.outputTemp = NULL;
+ mState.resampleTemp = NULL;
mState.hook = process__nop;
track_t* t = mState.tracks;
for (int i=0 ; i<32 ; i++) {
t->needs = 0;
t->volume[0] = UNITY_GAIN;
t->volume[1] = UNITY_GAIN;
+ // no initialization needed
+ // t->prevVolume[0]
+ // t->prevVolume[1]
t->volumeInc[0] = 0;
t->volumeInc[1] = 0;
t->auxLevel = 0;
t->auxInc = 0;
+ // no initialization needed
+ // t->prevAuxLevel
+ // t->frameCount
t->channelCount = 2;
t->enabled = 0;
t->format = 16;
t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
t->buffer.raw = 0;
- t->bufferProvider = 0;
- t->hook = 0;
- t->resampler = 0;
+ t->bufferProvider = NULL;
+ t->hook = NULL;
+ t->resampler = NULL;
t->sampleRate = mSampleRate;
- t->in = 0;
+ t->in = NULL;
t->mainBuffer = NULL;
t->auxBuffer = NULL;
t++;
}
}
- AudioMixer::~AudioMixer()
- {
- track_t* t = mState.tracks;
- for (int i=0 ; i<32 ; i++) {
- delete t->resampler;
- t++;
- }
- delete [] mState.outputTemp;
- delete [] mState.resampleTemp;
- }
+AudioMixer::~AudioMixer()
+{
+ track_t* t = mState.tracks;
+ for (int i=0 ; i<32 ; i++) {
+ delete t->resampler;
+ t++;
+ }
+ delete [] mState.outputTemp;
+ delete [] mState.resampleTemp;
+}
- int AudioMixer::getTrackName()
- {
+int AudioMixer::getTrackName()
+{
uint32_t names = mTrackNames;
uint32_t mask = 1;
int n = 0;
@@ -98,142 +107,131 @@
return TRACK0 + n;
}
return -1;
- }
+}
- void AudioMixer::invalidateState(uint32_t mask)
- {
+void AudioMixer::invalidateState(uint32_t mask)
+{
if (mask) {
mState.needsChanged |= mask;
mState.hook = process__validate;
}
}
- void AudioMixer::deleteTrackName(int name)
- {
+void AudioMixer::deleteTrackName(int name)
+{
name -= TRACK0;
- if (uint32_t(name) < MAX_NUM_TRACKS) {
- ALOGV("deleteTrackName(%d)", name);
- track_t& track(mState.tracks[ name ]);
- if (track.enabled != 0) {
- track.enabled = 0;
- invalidateState(1<<name);
- }
- if (track.resampler) {
- // delete the resampler
- delete track.resampler;
- track.resampler = 0;
- track.sampleRate = mSampleRate;
- invalidateState(1<<name);
- }
- track.volumeInc[0] = 0;
- track.volumeInc[1] = 0;
- mTrackNames &= ~(1<<name);
+ assert(uint32_t(name) < MAX_NUM_TRACKS);
+ ALOGV("deleteTrackName(%d)", name);
+ track_t& track(mState.tracks[ name ]);
+ if (track.enabled != 0) {
+ track.enabled = 0;
+ invalidateState(1<<name);
}
- }
-
-status_t AudioMixer::enable(int name)
-{
- switch (name) {
- case MIXING: {
- if (mState.tracks[ mActiveTrack ].enabled != 1) {
- mState.tracks[ mActiveTrack ].enabled = 1;
- ALOGV("enable(%d)", mActiveTrack);
- invalidateState(1<<mActiveTrack);
- }
- } break;
- default:
- return NAME_NOT_FOUND;
+ if (track.resampler) {
+ // delete the resampler
+ delete track.resampler;
+ track.resampler = NULL;
+ track.sampleRate = mSampleRate;
+ invalidateState(1<<name);
}
- return NO_ERROR;
+ track.volumeInc[0] = 0;
+ track.volumeInc[1] = 0;
+ mTrackNames &= ~(1<<name);
}
-status_t AudioMixer::disable(int name)
+void AudioMixer::enable()
{
- switch (name) {
- case MIXING: {
- if (mState.tracks[ mActiveTrack ].enabled != 0) {
- mState.tracks[ mActiveTrack ].enabled = 0;
- ALOGV("disable(%d)", mActiveTrack);
- invalidateState(1<<mActiveTrack);
- }
- } break;
- default:
- return NAME_NOT_FOUND;
+ if (mState.tracks[ mActiveTrack ].enabled != 1) {
+ mState.tracks[ mActiveTrack ].enabled = 1;
+ ALOGV("enable(%d)", mActiveTrack);
+ invalidateState(1<<mActiveTrack);
}
- return NO_ERROR;
}
-status_t AudioMixer::setActiveTrack(int track)
+void AudioMixer::disable()
{
- if (uint32_t(track-TRACK0) >= MAX_NUM_TRACKS) {
- return BAD_VALUE;
+ if (mState.tracks[ mActiveTrack ].enabled != 0) {
+ mState.tracks[ mActiveTrack ].enabled = 0;
+ ALOGV("disable(%d)", mActiveTrack);
+ invalidateState(1<<mActiveTrack);
}
- mActiveTrack = track - TRACK0;
- return NO_ERROR;
}
-status_t AudioMixer::setParameter(int target, int name, void *value)
+void AudioMixer::setActiveTrack(int track)
+{
+ // this also catches track < TRACK0
+ track -= TRACK0;
+ assert(uint32_t(track) < MAX_NUM_TRACKS);
+ mActiveTrack = track;
+}
+
+void AudioMixer::setParameter(int target, int name, void *value)
{
int valueInt = (int)value;
int32_t *valueBuf = (int32_t *)value;
switch (target) {
+
case TRACK:
- if (name == CHANNEL_MASK) {
+ switch (name) {
+ case CHANNEL_MASK: {
uint32_t mask = (uint32_t)value;
if (mState.tracks[ mActiveTrack ].channelMask != mask) {
uint8_t channelCount = popcount(mask);
- if ((channelCount <= MAX_NUM_CHANNELS) && (channelCount)) {
- mState.tracks[ mActiveTrack ].channelMask = mask;
- mState.tracks[ mActiveTrack ].channelCount = channelCount;
- ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
- invalidateState(1<<mActiveTrack);
- return NO_ERROR;
- }
- } else {
- return NO_ERROR;
+ assert((channelCount <= MAX_NUM_CHANNELS) && (channelCount));
+ mState.tracks[ mActiveTrack ].channelMask = mask;
+ mState.tracks[ mActiveTrack ].channelCount = channelCount;
+ ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
+ invalidateState(1<<mActiveTrack);
}
- }
- if (name == MAIN_BUFFER) {
+ } break;
+ case MAIN_BUFFER:
if (mState.tracks[ mActiveTrack ].mainBuffer != valueBuf) {
mState.tracks[ mActiveTrack ].mainBuffer = valueBuf;
ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
invalidateState(1<<mActiveTrack);
}
- return NO_ERROR;
- }
- if (name == AUX_BUFFER) {
+ break;
+ case AUX_BUFFER:
if (mState.tracks[ mActiveTrack ].auxBuffer != valueBuf) {
mState.tracks[ mActiveTrack ].auxBuffer = valueBuf;
ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
invalidateState(1<<mActiveTrack);
}
- return NO_ERROR;
+ break;
+ default:
+ // bad name
+ assert(false);
}
-
break;
+
case RESAMPLE:
- if (name == SAMPLE_RATE) {
- if (valueInt > 0) {
- track_t& track = mState.tracks[ mActiveTrack ];
- if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
- ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
- uint32_t(valueInt));
- invalidateState(1<<mActiveTrack);
- }
- return NO_ERROR;
+ switch (name) {
+ case SAMPLE_RATE: {
+ assert(valueInt > 0);
+ track_t& track = mState.tracks[ mActiveTrack ];
+ if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
+ ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
+ uint32_t(valueInt));
+ invalidateState(1<<mActiveTrack);
}
- }
- if (name == RESET) {
+ } break;
+ case RESET: {
track_t& track = mState.tracks[ mActiveTrack ];
track.resetResampler();
invalidateState(1<<mActiveTrack);
- return NO_ERROR;
+ } break;
+ default:
+ // bad name
+ assert(false);
}
break;
+
case RAMP_VOLUME:
case VOLUME:
- if ((uint32_t(name-VOLUME0) < MAX_NUM_CHANNELS)) {
+ switch (name) {
+ case VOLUME0:
+ case VOLUME1: {
track_t& track = mState.tracks[ mActiveTrack ];
if (track.volume[name-VOLUME0] != valueInt) {
ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
@@ -252,8 +250,8 @@
}
invalidateState(1<<mActiveTrack);
}
- return NO_ERROR;
- } else if (name == AUXLEVEL) {
+ } break;
+ case AUXLEVEL: {
track_t& track = mState.tracks[ mActiveTrack ];
if (track.auxLevel != valueInt) {
ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
@@ -272,11 +270,17 @@
}
invalidateState(1<<mActiveTrack);
}
- return NO_ERROR;
+ } break;
+ default:
+ // bad name
+ assert(false);
}
break;
+
+ default:
+ // bad target
+ assert(false);
}
- return BAD_VALUE;
}
bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
@@ -284,7 +288,7 @@
if (value!=devSampleRate || resampler) {
if (sampleRate != value) {
sampleRate = value;
- if (resampler == 0) {
+ if (resampler == NULL) {
resampler = AudioResampler::create(
format, channelCount, devSampleRate);
}
@@ -296,12 +300,12 @@
bool AudioMixer::track_t::doesResample() const
{
- return resampler != 0;
+ return resampler != NULL;
}
void AudioMixer::track_t::resetResampler()
{
- if (resampler != 0) {
+ if (resampler != NULL) {
resampler->reset();
}
}
@@ -326,10 +330,9 @@
}
-status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
+void AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
{
mState.tracks[ mActiveTrack ].bufferProvider = buffer;
- return NO_ERROR;
}
@@ -424,11 +427,11 @@
} else {
if (state->outputTemp) {
delete [] state->outputTemp;
- state->outputTemp = 0;
+ state->outputTemp = NULL;
}
if (state->resampleTemp) {
delete [] state->resampleTemp;
- state->resampleTemp = 0;
+ state->resampleTemp = NULL;
}
state->hook = process__genericNoResampling;
if (all16BitsStereoNoResample && !volumeRamp) {
@@ -444,33 +447,33 @@
countActiveTracks, state->enabledTracks,
all16BitsStereoNoResample, resampling, volumeRamp);
- state->hook(state);
+ state->hook(state);
- // Now that the volume ramp has been done, set optimal state and
- // track hooks for subsequent mixer process
- if (countActiveTracks) {
- int allMuted = 1;
- uint32_t en = state->enabledTracks;
- while (en) {
- const int i = 31 - __builtin_clz(en);
- en &= ~(1<<i);
- track_t& t = state->tracks[i];
- if (!t.doesResample() && t.volumeRL == 0)
- {
- t.needs |= NEEDS_MUTE_ENABLED;
- t.hook = track__nop;
- } else {
- allMuted = 0;
- }
- }
- if (allMuted) {
- state->hook = process__nop;
- } else if (all16BitsStereoNoResample) {
- if (countActiveTracks == 1) {
- state->hook = process__OneTrack16BitsStereoNoResampling;
- }
- }
- }
+ // Now that the volume ramp has been done, set optimal state and
+ // track hooks for subsequent mixer process
+ if (countActiveTracks) {
+ int allMuted = 1;
+ uint32_t en = state->enabledTracks;
+ while (en) {
+ const int i = 31 - __builtin_clz(en);
+ en &= ~(1<<i);
+ track_t& t = state->tracks[i];
+ if (!t.doesResample() && t.volumeRL == 0)
+ {
+ t.needs |= NEEDS_MUTE_ENABLED;
+ t.hook = track__nop;
+ } else {
+ allMuted = 0;
+ }
+ }
+ if (allMuted) {
+ state->hook = process__nop;
+ } else if (all16BitsStereoNoResample) {
+ if (countActiveTracks == 1) {
+ state->hook = process__OneTrack16BitsStereoNoResampling;
+ }
+ }
+ }
}
@@ -892,7 +895,7 @@
}
- // generic code with resampling
+// generic code with resampling
void AudioMixer::process__genericResampling(state_t* state)
{
int32_t* const outTemp = state->outputTemp;
@@ -1072,7 +1075,7 @@
}
in1 = buff;
b1.frameCount = numFrames;
- } else {
+ } else {
in1 = b1.i16;
}
frameCount1 = b1.frameCount;
@@ -1114,4 +1117,3 @@
// ----------------------------------------------------------------------------
}; // namespace android
-
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index bdbbaf3..c4a7871 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -50,8 +50,7 @@
// track units (32 units)
TRACK0 = 0x1000,
- // enable/disable
- MIXING = 0x2000,
+ // 0x2000 is unused
// setParameter targets
TRACK = 0x3000,
@@ -65,10 +64,10 @@
FORMAT = 0x4001,
MAIN_BUFFER = 0x4002,
AUX_BUFFER = 0x4003,
- // for TARGET RESAMPLE
+ // for target RESAMPLE
SAMPLE_RATE = 0x4100,
RESET = 0x4101,
- // for TARGET VOLUME (8 channels max)
+ // for target RAMP_VOLUME and VOLUME (8 channels max)
VOLUME0 = 0x4200,
VOLUME1 = 0x4201,
AUXLEVEL = 0x4210,
@@ -78,13 +77,13 @@
int getTrackName();
void deleteTrackName(int name);
- status_t enable(int name);
- status_t disable(int name);
+ void enable();
+ void disable();
- status_t setActiveTrack(int track);
- status_t setParameter(int target, int name, void *value);
+ void setActiveTrack(int track);
+ void setParameter(int target, int name, void *value);
- status_t setBufferProvider(AudioBufferProvider* bufferProvider);
+ void setBufferProvider(AudioBufferProvider* bufferProvider);
void process();
uint32_t trackNames() const { return mTrackNames; }
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 840d70d..bc4c90c 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -31,7 +31,6 @@
#include <utils/threads.h>
#include "AudioPolicyService.h"
#include <cutils/properties.h>
-#include <dlfcn.h>
#include <hardware_legacy/power.h>
#include <media/AudioEffect.h>
#include <media/EffectsFactoryApi.h>
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index d898a53..88cb1e9 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -19,6 +19,7 @@
#include <cutils/misc.h>
#include <cutils/config_utils.h>
+#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/SortedVector.h>
#include <binder/BinderService.h>
@@ -31,8 +32,6 @@
namespace android {
-class String8;
-
// ----------------------------------------------------------------------------
class AudioPolicyService :