summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/AudioTrack.h2
-rw-r--r--media/libmedia/AudioTrack.cpp2
-rw-r--r--media/libnbaio/README.txt40
-rw-r--r--services/audioflinger/AudioFlinger.cpp13
-rw-r--r--services/audioflinger/AudioFlinger.h11
-rw-r--r--services/camera/libcameraservice/Camera2Device.cpp7
6 files changed, 62 insertions, 13 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 26a25b0..34108b3 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -547,7 +547,7 @@ public:
status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer);
/* queue a buffer obtained via allocateTimedBuffer for playback at the
- given timestamp. PTS units a microseconds on the media time timeline.
+ given timestamp. PTS units are microseconds on the media time timeline.
The media time transform (set with setMediaTimeTransform) set by the
audio producer will handle converting from media time to local time
(perhaps going through the common time timeline in the case of
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 73d396e..362d022 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1144,7 +1144,7 @@ status_t TimedAudioTrack::allocateTimedBuffer(size_t size, sp<IMemory>* buffer)
// 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 in just a bit.
+ // we can attempt to restore in just a bit.
if (!(mCblk->flags & CBLK_INVALID_MSK)) {
result = mAudioTrack->allocateTimedBuffer(size, buffer);
if (result == DEAD_OBJECT) {
diff --git a/media/libnbaio/README.txt b/media/libnbaio/README.txt
new file mode 100644
index 0000000..8d74ab2
--- /dev/null
+++ b/media/libnbaio/README.txt
@@ -0,0 +1,40 @@
+libnbaio (for "Non-Blocking Audio I/O") was originally intended to
+be a purely non-blocking API. It has evolved to now include
+a few blocking implementations of the interface.
+
+Note: as used here, "short transfer count" means the return value for
+read() or write() that indicates the actual number of successfully
+transferred frames is less than the requested number of frames.
+
+Pipe
+----
+supports 1 writer and N readers
+
+no mutexes, so safe to use between SCHED_NORMAL and SCHED_FIFO threads
+
+writes:
+ non-blocking
+ never return a short transfer count
+ overwrite data if not consumed quickly enough
+
+reads:
+ non-blocking
+ return a short transfer count if not enough data
+ will lose data if reader doesn't keep up
+
+MonoPipe
+--------
+supports 1 writer and 1 reader
+
+no mutexes, so safe to use between SCHED_NORMAL and SCHED_FIFO threads
+
+write are optionally blocking:
+ if configured to block, then will wait until space available before returning
+ if configured to not block, then will return a short transfer count
+ and will never overwrite data
+
+reads:
+ non-blocking
+ return a short transfer count if not enough data
+ never lose data
+
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 1a37f4f..14f74b5 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -169,8 +169,8 @@ static const int kPriorityFastMixer = 3;
// for the track. The client then sub-divides this into smaller buffers for its use.
// Currently the client uses double-buffering by default, but doesn't tell us about that.
// So for now we just assume that client is double-buffered.
-// FIXME It would be better for client to tell us whether it wants double-buffering or N-buffering,
-// so we could allocate the right amount of memory.
+// FIXME It would be better for client to tell AudioFlinger whether it wants double-buffering or
+// N-buffering, so AudioFlinger could allocate the right amount of memory.
// See the client's minBufCount and mNotificationFramesAct calculations for details.
static const int kFastTrackMultiplier = 2;
@@ -258,11 +258,11 @@ void AudioFlinger::onFirstRef()
AudioFlinger::~AudioFlinger()
{
while (!mRecordThreads.isEmpty()) {
- // closeInput() will remove first entry from mRecordThreads
+ // closeInput_nonvirtual() will remove specified entry from mRecordThreads
closeInput_nonvirtual(mRecordThreads.keyAt(0));
}
while (!mPlaybackThreads.isEmpty()) {
- // closeOutput() will remove first entry from mPlaybackThreads
+ // closeOutput_nonvirtual() will remove specified entry from mPlaybackThreads
closeOutput_nonvirtual(mPlaybackThreads.keyAt(0));
}
@@ -1134,7 +1134,7 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(int sessionId,
AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
audio_devices_t device, type_t type)
- : Thread(false),
+ : Thread(false /*canCallJava*/),
mType(type),
mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mNormalFrameCount(0),
// mChannelMask
@@ -1142,6 +1142,7 @@ AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio
mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),
mParamStatus(NO_ERROR),
mStandby(false), mDevice(device), mId(id),
+ // mName will be set by concrete (non-virtual) subclass
mDeathRecipient(new PMDeathRecipient(this))
{
}
@@ -6097,7 +6098,7 @@ bool AudioFlinger::RecordThread::threadLoop()
if (mChannelCount == 1 && mReqChannelCount == 1) {
framesOut >>= 1;
}
- mResampler->resample(mRsmpOutBuffer, framesOut, this);
+ mResampler->resample(mRsmpOutBuffer, framesOut, this /* AudioBufferProvider* */);
// ditherAndClamp() works as long as all buffers returned by mActiveTrack->getNextBuffer()
// are 32 bit aligned which should be always true.
if (mChannelCount == 2 && mReqChannelCount == 1) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index b4aefc1..4723cd9 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -454,8 +454,9 @@ private:
/*const*/ sp<Client> mClient; // see explanation at ~TrackBase() why not const
sp<IMemory> mCblkMemory;
audio_track_cblk_t* mCblk;
- void* mBuffer;
- void* mBufferEnd;
+ void* mBuffer; // start of track buffer, typically in shared memory
+ void* mBufferEnd; // &mBuffer[mFrameCount * frameSize], where frameSize
+ // is based on mChannelCount and 16-bit samples
uint32_t mFrameCount;
// we don't really need a lock for these
track_state mState;
@@ -1364,6 +1365,7 @@ private:
// record thread
class RecordThread : public ThreadBase, public AudioBufferProvider
+ // derives from AudioBufferProvider interface for use by resampler
{
public:
@@ -1420,7 +1422,7 @@ private:
void dumpInternals(int fd, const Vector<String16>& args);
void dumpTracks(int fd, const Vector<String16>& args);
- // Thread
+ // Thread virtuals
virtual bool threadLoop();
virtual status_t readyToRun();
@@ -1968,9 +1970,10 @@ mutable Mutex mLock; // mutex for process, commands and handl
DefaultKeyedVector< audio_io_handle_t, sp<PlaybackThread> > mPlaybackThreads;
stream_type_t mStreamTypes[AUDIO_STREAM_CNT];
- // both are protected by mLock
+ // member variables below are protected by mLock
float mMasterVolume;
bool mMasterMute;
+ // end of variables protected by mLock
DefaultKeyedVector< audio_io_handle_t, sp<RecordThread> > mRecordThreads;
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index 7cac025..f62c0a0 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -109,7 +109,12 @@ status_t Camera2Device::initialize(camera_module_t *module)
__FUNCTION__, mId, strerror(-res), res);
return res;
}
-
+ res = set_camera_metadata_vendor_tag_ops(mVendorTagOps);
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
+ __FUNCTION__, mId, strerror(-res), res);
+ return res;
+ }
setNotifyCallback(NULL);
return OK;