summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/AudioRecord.h33
-rw-r--r--include/media/AudioSystem.h2
-rw-r--r--include/media/AudioTrack.h7
-rw-r--r--include/media/IAudioFlinger.h2
-rw-r--r--media/libmedia/AudioRecord.cpp10
-rw-r--r--media/libmedia/AudioSystem.cpp4
-rw-r--r--media/libmedia/AudioTrack.cpp5
-rw-r--r--media/libmedia/IAudioFlinger.cpp11
-rw-r--r--media/libstagefright/AudioSource.cpp2
-rw-r--r--services/audioflinger/AudioFlinger.cpp2
-rw-r--r--services/audioflinger/AudioFlinger.h2
-rw-r--r--services/audioflinger/Threads.cpp2
-rw-r--r--services/audioflinger/Threads.h2
13 files changed, 51 insertions, 33 deletions
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 0439cb0..c724949 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -39,8 +39,12 @@ public:
* Keep in sync with frameworks/base/media/java/android/media/AudioRecord.java NATIVE_EVENT_*.
*/
enum event_type {
- EVENT_MORE_DATA = 0, // Request to read more data from PCM buffer.
- EVENT_OVERRUN = 1, // PCM buffer overrun occurred.
+ EVENT_MORE_DATA = 0, // Request to read available data from buffer.
+ // If this event is delivered but the callback handler
+ // does not want to read the available data, the handler must
+ // explicitly
+ // ignore the event by setting frameCount to zero.
+ EVENT_OVERRUN = 1, // 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
@@ -63,6 +67,7 @@ public:
// (currently ignored but will make the primary field in future)
size_t size; // input/output in bytes == frameCount * frameSize
+ // on output is the number of bytes actually drained
// FIXME this is redundant with respect to frameCount,
// and TRANSFER_OBTAIN mode is broken for 8-bit data
// since we don't define the frame format
@@ -76,7 +81,7 @@ public:
/* 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 various conditions occur.
+ * invokes the callback when a new buffer becomes available or various conditions occur.
* Parameters:
*
* event: type of event notified (see enum AudioRecord::event_type).
@@ -99,6 +104,8 @@ public:
* - NO_ERROR: successful operation
* - NO_INIT: audio server or audio hardware not initialized
* - BAD_VALUE: unsupported configuration
+ * frameCount is guaranteed to be non-zero if status is NO_ERROR,
+ * and is undefined otherwise.
*/
static status_t getMinFrameCount(size_t* frameCount,
@@ -109,7 +116,7 @@ public:
/* How data is transferred from AudioRecord
*/
enum transfer_type {
- TRANSFER_DEFAULT, // not specified explicitly; determine from other parameters
+ TRANSFER_DEFAULT, // not specified explicitly; determine from the other parameters
TRANSFER_CALLBACK, // callback EVENT_MORE_DATA
TRANSFER_OBTAIN, // FIXME deprecated: call obtainBuffer() and releaseBuffer()
TRANSFER_SYNC, // synchronous read()
@@ -137,7 +144,7 @@ public:
* 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 consume new PCM data and inform of marker, position updates, etc.
+ * to consume new data and inform of marker, position updates, etc.
* 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.
@@ -171,9 +178,10 @@ public:
* Returned status (from utils/Errors.h) can be:
* - NO_ERROR: successful intialization
* - INVALID_OPERATION: AudioRecord is already initialized or record device is already in use
- * - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
+ * - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...)
* - NO_INIT: audio server or audio hardware not initialized
* - PERMISSION_DENIED: recording is not allowed for the requesting process
+ * If status is not equal to NO_ERROR, don't call any other APIs on this AudioRecord.
*
* Parameters not listed in the AudioRecord constructors above:
*
@@ -192,7 +200,7 @@ public:
transfer_type transferType = TRANSFER_DEFAULT,
audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE);
- /* Result of constructing the AudioRecord. This must be checked
+ /* Result of constructing the AudioRecord. This must be checked for successful initialization
* before using any AudioRecord API (except for set()), because using
* an uninitialized AudioRecord produces undefined results.
* See set() method above for possible return codes.
@@ -221,7 +229,7 @@ public:
status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
int triggerSession = 0);
- /* Stop a track. If set, the callback will cease being called. Note that obtainBuffer() still
+ /* Stop a track. The callback will cease being called. Note that obtainBuffer() still
* works and will drain buffers until the pool is exhausted, and then will return WOULD_BLOCK.
*/
void stop();
@@ -236,7 +244,7 @@ public:
* a callback with event type EVENT_MARKER is called. Calling setMarkerPosition
* with marker == 0 cancels marker notification callback.
* To set a marker at a position which would compute as 0,
- * a workaround is to the set the marker at a nearby position such as ~0 or 1.
+ * a workaround is to set the marker at a nearby position such as ~0 or 1.
* If the AudioRecord has been opened with no callback function associated,
* the operation will fail.
*
@@ -378,8 +386,10 @@ public:
* 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.
* Units: the number of input audio frames.
+ * FIXME The side-effect of resetting the counter may be incompatible with multi-client.
+ * Consider making it more like AudioTrack::getUnderrunFrames which doesn't have side effects.
*/
- unsigned int getInputFramesLost() const;
+ uint32_t getInputFramesLost() const;
private:
/* copying audio record objects is not allowed */
@@ -426,6 +436,7 @@ private:
nsecs_t processAudioBuffer();
// caller must hold lock on mLock for all _l methods
+
status_t openRecord_l(size_t epoch);
// FIXME enum is faster than strcmp() for parameter 'from'
@@ -477,7 +488,7 @@ private:
audio_io_handle_t mInput; // returned by AudioSystem::getInput()
- // may be changed if IAudioRecord object is re-created
+ // Next 3 fields may be changed if IAudioRecord is re-created, but always != 0
sp<IAudioRecord> mAudioRecord;
sp<IMemory> mCblkMemory;
audio_track_cblk_t* mCblk; // re-load after mLock.unlock()
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index ca9aaf7..706344a 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -138,7 +138,7 @@ public:
audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
// return the number of input frames lost by HAL implementation, or 0 if the handle is invalid
- static size_t getInputFramesLost(audio_io_handle_t ioHandle);
+ static uint32_t getInputFramesLost(audio_io_handle_t ioHandle);
static int newAudioSessionId();
static void acquireAudioSessionId(int audioSession);
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index c86a67b..88a5a4c 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -160,7 +160,7 @@ public:
* sampleRate: Data source sampling rate in Hz.
* format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
* 16 bits per sample).
- * channelMask: Channel mask.
+ * channelMask: Channel mask, such that audio_is_output_channel(channelMask) is true.
* 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 AudioTrack could be
@@ -338,7 +338,7 @@ public:
*/
status_t setSampleRate(uint32_t sampleRate);
- /* Return current source sample rate in Hz, or 0 if unknown */
+ /* Return current source sample rate in Hz */
uint32_t getSampleRate() const;
/* Enables looping and sets the start and end points of looping.
@@ -363,7 +363,7 @@ public:
/* 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. To set a marker at a position which would compute as 0,
- * a workaround is to the set the marker at a nearby position such as ~0 or 1.
+ * a workaround is to set the marker at a nearby position such as ~0 or 1.
* If the AudioTrack has been opened with no callback function associated, the operation will
* fail.
*
@@ -717,6 +717,7 @@ protected:
sp<IMemory> mSharedBuffer;
uint32_t mLoopPeriod; // in frames, zero means looping is disabled
+
uint32_t mMarkerPosition; // in wrapping (overflow) frame units
bool mMarkerReached;
uint32_t mNewPosition; // in frames
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 899d79f..c9cffe3 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -170,7 +170,7 @@ public:
virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
audio_io_handle_t output) const = 0;
- virtual size_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
+ virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
virtual int newAudioSessionId() = 0;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 3a0f222..7183193 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -355,6 +355,7 @@ bool AudioRecord::stopped() const
status_t AudioRecord::setMarkerPosition(uint32_t marker)
{
+ // The only purpose of setting marker position is to get a callback
if (mCbf == NULL) {
return INVALID_OPERATION;
}
@@ -380,6 +381,7 @@ status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
{
+ // The only purpose of setting position update period is to get a callback
if (mCbf == NULL) {
return INVALID_OPERATION;
}
@@ -415,7 +417,7 @@ status_t AudioRecord::getPosition(uint32_t *position) const
return NO_ERROR;
}
-unsigned int AudioRecord::getInputFramesLost() const
+uint32_t AudioRecord::getInputFramesLost() const
{
// no need to check mActive, because if inactive this will return 0, which is what we want
return AudioSystem::getInputFramesLost(getInput());
@@ -773,7 +775,7 @@ nsecs_t AudioRecord::processAudioBuffer()
int32_t sequence = mSequence;
// These fields don't need to be cached, because they are assigned only by set():
- // mTransfer, mCbf, mUserData, mSampleRate
+ // mTransfer, mCbf, mUserData, mSampleRate, mFrameSize
mLock.unlock();
@@ -847,8 +849,8 @@ nsecs_t AudioRecord::processAudioBuffer()
"obtainBuffer() err=%d frameCount=%u", err, audioBuffer.frameCount);
requested = &ClientProxy::kNonBlocking;
size_t avail = audioBuffer.frameCount + nonContig;
- ALOGV("obtainBuffer(%u) returned %u = %u + %u",
- mRemainingFrames, avail, audioBuffer.frameCount, nonContig);
+ ALOGV("obtainBuffer(%u) returned %u = %u + %u err %d",
+ mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
if (err != NO_ERROR) {
if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) {
break;
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 69d9273..dcb72f8 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -413,9 +413,9 @@ status_t AudioSystem::getRenderPosition(audio_io_handle_t output, size_t *halFra
return af->getRenderPosition(halFrames, dspFrames, output);
}
-size_t AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
+uint32_t AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
- unsigned int result = 0;
+ uint32_t result = 0;
if (af == 0) return result;
if (ioHandle == 0) return result;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index d5e3e67..f5a010b 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -355,7 +355,7 @@ status_t AudioTrack::set(
mAudioTrackThread->requestExitAndWait();
mAudioTrackThread.clear();
}
- //Use of direct and offloaded output streams is ref counted by audio policy manager.
+ // Use of direct and offloaded output streams is ref counted by audio policy manager.
// As getOutput was called above and resulted in an output stream to be opened,
// we need to release it.
AudioSystem::releaseOutput(output);
@@ -698,6 +698,7 @@ status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod)
AutoMutex lock(mLock);
mNewPosition = mProxy->getPosition() + updatePeriod;
mUpdatePeriod = updatePeriod;
+
return NO_ERROR;
}
@@ -1735,7 +1736,7 @@ status_t AudioTrack::restoreTrack_l(const char *from)
}
}
if (result != NO_ERROR) {
- //Use of direct and offloaded output streams is ref counted by audio policy manager.
+ // Use of direct and offloaded output streams is ref counted by audio policy manager.
// As getOutput was called above and resulted in an output stream to be opened,
// we need to release it.
AudioSystem::releaseOutput(output);
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index c9c8d58..3aaff88 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -564,13 +564,16 @@ public:
return status;
}
- virtual size_t getInputFramesLost(audio_io_handle_t ioHandle) const
+ virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
data.writeInt32((int32_t) ioHandle);
- remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply);
- return reply.readInt32();
+ status_t status = remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply);
+ if (status != NO_ERROR) {
+ return 0;
+ }
+ return (uint32_t) reply.readInt32();
}
virtual int newAudioSessionId()
@@ -1044,7 +1047,7 @@ status_t BnAudioFlinger::onTransact(
case GET_INPUT_FRAMES_LOST: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
- reply->writeInt32(getInputFramesLost(ioHandle));
+ reply->writeInt32((int32_t) getInputFramesLost(ioHandle));
return NO_ERROR;
} break;
case NEW_AUDIO_SESSION_ID: {
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index d7223d9..cadadc8 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -278,7 +278,7 @@ status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
// Drop retrieved and previously lost audio data.
if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
- mRecord->getInputFramesLost();
+ (void) mRecord->getInputFramesLost();
ALOGV("Drop audio data at %lld/%lld us", timeUs, mStartTimeUs);
return OK;
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 34811a7..780ecf1 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1058,7 +1058,7 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t form
return size;
}
-unsigned int AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
+uint32_t AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
{
Mutex::Autolock _l(mLock);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 066d5d5..0ab43e0 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -189,7 +189,7 @@ public:
virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
audio_io_handle_t output) const;
- virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const;
+ virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const;
virtual int newAudioSessionId();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 01b90a8..a79d0e3 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -5371,7 +5371,7 @@ void AudioFlinger::RecordThread::readInputParameters()
mRsmpInIndex = mFrameCount;
}
-unsigned int AudioFlinger::RecordThread::getInputFramesLost()
+uint32_t AudioFlinger::RecordThread::getInputFramesLost()
{
Mutex::Autolock _l(mLock);
if (initCheck() != NO_ERROR) {
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 6b81c38..2b749fa 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -907,7 +907,7 @@ public:
virtual String8 getParameters(const String8& keys);
virtual void audioConfigChanged_l(int event, int param = 0);
void readInputParameters();
- virtual unsigned int getInputFramesLost();
+ virtual uint32_t getInputFramesLost();
virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);