Merge "Move declarations of local variables to first use"
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index ef77692..813ea85 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -17,21 +17,14 @@
#ifndef AUDIORECORD_H_
#define AUDIORECORD_H_
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <media/IAudioFlinger.h>
-#include <media/IAudioRecord.h>
-
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
#include <binder/IMemory.h>
#include <cutils/sched_policy.h>
-#include <utils/threads.h>
-
-#include <system/audio.h>
#include <media/AudioSystem.h>
+#include <media/IAudioRecord.h>
+#include <system/audio.h>
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
namespace android {
@@ -46,11 +39,10 @@
static const int DEFAULT_SAMPLE_RATE = 8000;
/* Events used by AudioRecord callback function (callback_t).
- *
- * to keep in sync with frameworks/base/media/java/android/media/AudioRecord.java
+ * Keep in sync with frameworks/base/media/java/android/media/AudioRecord.java NATIVE_EVENT_*.
*/
enum event_type {
- EVENT_MORE_DATA = 0, // Request to reqd more data from PCM buffer.
+ EVENT_MORE_DATA = 0, // Request to read more data from PCM buffer.
EVENT_OVERRUN = 1, // PCM buffer overrun occured.
EVENT_MARKER = 2, // Record head is at the specified marker position
// (See setMarkerPosition()).
@@ -72,7 +64,7 @@
int channelCount;
audio_format_t format;
size_t frameCount;
- size_t size;
+ size_t size; // total size in bytes == frameCount * frameSize
union {
void* raw;
short* i16;
@@ -115,7 +107,7 @@
static status_t getMinFrameCount(int* frameCount,
uint32_t sampleRate,
audio_format_t format,
- int channelCount);
+ audio_channel_mask_t channelMask);
/* Constructs an uninitialized AudioRecord. No connection with
* AudioFlinger takes place.
@@ -133,32 +125,22 @@
* sampleRate: Track sampling rate in Hz.
* format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
* 16 bits per sample).
- * channelMask: Channel mask: see audio_channels_t.
+ * channelMask: Channel mask.
* frameCount: Total size of track PCM buffer in frames. This defines the
* latency of the track.
- * flags: A bitmask of acoustic values from enum record_flags. It enables
- * AGC, NS, and IIR.
* cbf: Callback function. If not null, this function is called periodically
* to provide 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.
- * user Context for use by the callback receiver.
+ * sessionId: Not yet supported.
*/
- // FIXME consider removing this alias and replacing it by audio_in_acoustics_t
- // or removing the parameter entirely if it is unused
- enum record_flags {
- RECORD_AGC_ENABLE = AUDIO_IN_ACOUSTICS_AGC_ENABLE,
- RECORD_NS_ENABLE = AUDIO_IN_ACOUSTICS_NS_ENABLE,
- RECORD_IIR_ENABLE = AUDIO_IN_ACOUSTICS_TX_IIR_ENABLE,
- };
-
AudioRecord(audio_source_t inputSource,
uint32_t sampleRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
- uint32_t channelMask = AUDIO_CHANNEL_IN_MONO,
+ audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_MONO,
int frameCount = 0,
- record_flags flags = (record_flags) 0,
callback_t cbf = NULL,
void* user = NULL,
int notificationFrames = 0,
@@ -166,7 +148,7 @@
/* Terminates the AudioRecord and unregisters it from AudioFlinger.
- * Also destroys all resources assotiated with the AudioRecord.
+ * Also destroys all resources associated with the AudioRecord.
*/
~AudioRecord();
@@ -182,9 +164,8 @@
status_t set(audio_source_t inputSource = AUDIO_SOURCE_DEFAULT,
uint32_t sampleRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
- uint32_t channelMask = AUDIO_CHANNEL_IN_MONO,
+ audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_MONO,
int frameCount = 0,
- record_flags flags = (record_flags) 0,
callback_t cbf = NULL,
void* user = NULL,
int notificationFrames = 0,
@@ -205,11 +186,10 @@
*/
uint32_t latency() const;
- /* getters, see constructor */
+ /* getters, see constructor and set() */
audio_format_t format() const;
int channelCount() const;
- int channels() const;
uint32_t frameCount() const;
size_t frameSize() const;
audio_source_t inputSource() const;
@@ -271,7 +251,7 @@
status_t getPositionUpdatePeriod(uint32_t *updatePeriod) const;
- /* Gets record head position. The position is the total number of frames
+ /* Gets record head position. The position is the total number of frames
* recorded since record start.
*
* Parameters:
@@ -294,7 +274,7 @@
*/
audio_io_handle_t getInput() const;
- /* returns the audio session ID associated to this AudioRecord.
+ /* returns the audio session ID associated with this AudioRecord.
*
* Parameters:
* none.
@@ -357,42 +337,47 @@
bool processAudioBuffer(const sp<ClientRecordThread>& thread);
status_t openRecord_l(uint32_t sampleRate,
audio_format_t format,
- uint32_t channelMask,
+ audio_channel_mask_t channelMask,
int frameCount,
audio_io_handle_t input);
audio_io_handle_t getInput_l();
status_t restoreRecord_l(audio_track_cblk_t*& cblk);
- sp<IAudioRecord> mAudioRecord;
- sp<IMemory> mCblkMemory;
sp<ClientRecordThread> mClientRecordThread;
status_t mReadyToRun;
mutable Mutex mLock;
Condition mCondition;
- uint32_t mFrameCount;
+ volatile int32_t mActive;
- audio_track_cblk_t* mCblk;
+ // for client callback handler
+ callback_t mCbf;
+ void* mUserData;
+
+ // for notification APIs
+ uint32_t mNotificationFrames;
+ uint32_t mRemainingFrames;
+ uint32_t mMarkerPosition; // in frames
+ bool mMarkerReached;
+ uint32_t mNewPosition; // in frames
+ uint32_t mUpdatePeriod; // in ms
+
+ // constant after constructor or set()
+ uint32_t mFrameCount;
audio_format_t mFormat;
uint8_t mChannelCount;
audio_source_t mInputSource;
status_t mStatus;
uint32_t mLatency;
-
- volatile int32_t mActive;
-
- callback_t mCbf;
- void* mUserData;
- uint32_t mNotificationFrames;
- uint32_t mRemainingFrames;
- uint32_t mMarkerPosition;
- bool mMarkerReached;
- uint32_t mNewPosition;
- uint32_t mUpdatePeriod;
- record_flags mFlags;
- uint32_t mChannelMask;
- audio_io_handle_t mInput;
+ audio_channel_mask_t mChannelMask;
+ audio_io_handle_t mInput; // returned by AudioSystem::getInput()
int mSessionId;
+
+ // may be changed if IAudioRecord object is re-created
+ sp<IAudioRecord> mAudioRecord;
+ sp<IMemory> mCblkMemory;
+ audio_track_cblk_t* mCblk;
+
int mPreviousPriority; // before start()
SchedPolicy mPreviousSchedulingGroup;
};
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index e2662f2..18c9c92 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -110,8 +110,8 @@
static bool routedToA2dpOutput(audio_stream_type_t streamType);
- static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount,
- size_t* buffSize);
+ static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask, size_t* buffSize);
static status_t setVoiceVolume(float volume);
@@ -201,7 +201,6 @@
uint32_t samplingRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = AUDIO_CHANNEL_IN_MONO,
- audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0,
int sessionId = 0);
static status_t startInput(audio_io_handle_t input);
static status_t stopInput(audio_io_handle_t input);
@@ -277,7 +276,7 @@
// previous parameters for recording buffer size queries
static uint32_t gPrevInSamplingRate;
static audio_format_t gPrevInFormat;
- static int gPrevInChannelCount;
+ static audio_channel_mask_t gPrevInChannelMask;
static sp<IAudioPolicyService> gAudioPolicyService;
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 86e228b..5d95b3b 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -60,7 +60,7 @@
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
- uint32_t channelMask,
+ audio_channel_mask_t channelMask,
int frameCount,
track_flags_t flags,
const sp<IMemory>& sharedBuffer,
@@ -74,7 +74,7 @@
audio_io_handle_t input,
uint32_t sampleRate,
audio_format_t format,
- uint32_t channelMask,
+ audio_channel_mask_t channelMask,
int frameCount,
track_flags_t flags,
int *sessionId,
@@ -84,7 +84,9 @@
* and therefore can be cached.
*/
virtual uint32_t sampleRate(audio_io_handle_t output) const = 0;
+#if 0
virtual int channelCount(audio_io_handle_t output) const = 0;
+#endif
virtual audio_format_t format(audio_io_handle_t output) const = 0;
virtual size_t frameCount(audio_io_handle_t output) const = 0;
@@ -126,7 +128,8 @@
virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;
// retrieve the audio recording buffer size
- virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const = 0;
+ virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask) const = 0;
virtual audio_io_handle_t openOutput(audio_module_handle_t module,
audio_devices_t *pDevices,
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index e160d70..23fa964 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -64,7 +64,6 @@
uint32_t samplingRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
- audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0,
int audioSession = 0) = 0;
virtual status_t startInput(audio_io_handle_t input) = 0;
virtual status_t stopInput(audio_io_handle_t input) = 0;
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
index e25d444..4a8e221 100644
--- a/include/media/stagefright/SurfaceMediaSource.h
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -79,10 +79,6 @@
MediaBuffer **buffer, const ReadOptions *options = NULL);
virtual sp<MetaData> getFormat();
- // Pass the metadata over to the buffer, call when you have the lock
- void passMetadataBufferLocked(MediaBuffer **buffer);
- bool checkBufferMatchesSlot(int slot, MediaBuffer *buffer);
-
// Get / Set the frame rate used for encoding. Default fps = 30
status_t setFrameRate(int32_t fps) ;
int32_t getFrameRate( ) const;
@@ -105,9 +101,6 @@
// when a new frame becomes available.
void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
- // getCurrentBuffer returns the buffer associated with the current image.
- sp<GraphicBuffer> getCurrentBuffer() const;
-
// dump our state in a String
void dump(String8& result) const;
void dump(String8& result, const char* prefix, char* buffer,
@@ -165,11 +158,12 @@
// reset mCurrentTexture to INVALID_BUFFER_SLOT.
int mCurrentSlot;
- // mCurrentBuf is the graphic buffer of the current slot to be used by
- // buffer consumer. It's possible that this buffer is not associated
- // with any buffer slot, so we must track it separately in order to
- // properly use IGraphicBufferAlloc::freeAllGraphicBuffersExcept.
- sp<GraphicBuffer> mCurrentBuf;
+ // mCurrentBuffers is a list of the graphic buffers that are being used by
+ // buffer consumer (i.e. the video encoder). It's possible that these
+ // buffers are not associated with any buffer slots, so we must track them
+ // separately. Buffers are added to this list in read, and removed from
+ // this list in signalBufferReturned
+ Vector<sp<GraphicBuffer> > mCurrentBuffers;
// mCurrentTimestamp is the timestamp for the current texture. It
// gets set to mLastQueuedTimestamp each time updateTexImage is called.
diff --git a/libvideoeditor/lvpp/Android.mk b/libvideoeditor/lvpp/Android.mk
index c018d74..0ed7e6c 100755
--- a/libvideoeditor/lvpp/Android.mk
+++ b/libvideoeditor/lvpp/Android.mk
@@ -59,6 +59,7 @@
libstagefright \
libstagefright_foundation \
libstagefright_omx \
+ libsync \
libui \
libutils \
libvideoeditor_osal \
diff --git a/libvideoeditor/lvpp/NativeWindowRenderer.cpp b/libvideoeditor/lvpp/NativeWindowRenderer.cpp
index b2c2675..2e15ff9 100755
--- a/libvideoeditor/lvpp/NativeWindowRenderer.cpp
+++ b/libvideoeditor/lvpp/NativeWindowRenderer.cpp
@@ -22,9 +22,9 @@
#include <cutils/log.h>
#include <gui/SurfaceTexture.h>
#include <gui/SurfaceTextureClient.h>
-#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/foundation/ADebug.h>
#include "VideoEditorTools.h"
#define CHECK_EGL_ERROR CHECK(EGL_SUCCESS == eglGetError())
@@ -382,7 +382,7 @@
int64_t timeUs;
CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
native_window_set_buffers_timestamp(anw, timeUs * 1000);
- status_t err = anw->queueBuffer(anw, buffer->graphicBuffer().get());
+ status_t err = anw->queueBuffer(anw, buffer->graphicBuffer().get(), -1);
if (err != 0) {
ALOGE("queueBuffer failed with error %s (%d)", strerror(-err), -err);
return;
@@ -399,18 +399,16 @@
native_window_set_usage(anw, GRALLOC_USAGE_SW_WRITE_OFTEN);
ANativeWindowBuffer* anb;
- anw->dequeueBuffer(anw, &anb);
+ CHECK(NO_ERROR == native_window_dequeue_buffer_and_wait(anw, &anb));
CHECK(anb != NULL);
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- CHECK(NO_ERROR == anw->lockBuffer(anw, buf->getNativeBuffer()));
-
// Copy the buffer
uint8_t* img = NULL;
+ sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
copyI420Buffer(buffer, img, width, height, buf->getStride());
buf->unlock();
- CHECK(NO_ERROR == anw->queueBuffer(anw, buf->getNativeBuffer()));
+ CHECK(NO_ERROR == anw->queueBuffer(anw, buf->getNativeBuffer(), -1));
}
void NativeWindowRenderer::copyI420Buffer(MediaBuffer* src, uint8_t* dst,
diff --git a/libvideoeditor/lvpp/PreviewRenderer.cpp b/libvideoeditor/lvpp/PreviewRenderer.cpp
index 4aa4eb3..b1cfc8e 100755
--- a/libvideoeditor/lvpp/PreviewRenderer.cpp
+++ b/libvideoeditor/lvpp/PreviewRenderer.cpp
@@ -97,13 +97,12 @@
void PreviewRenderer::getBufferYV12(uint8_t **data, size_t *stride) {
int err = OK;
- if ((err = mSurface->ANativeWindow::dequeueBuffer(mSurface.get(), &mBuf)) != 0) {
- ALOGW("Surface::dequeueBuffer returned error %d", err);
+ if ((err = native_window_dequeue_buffer_and_wait(mSurface.get(),
+ &mBuf)) != 0) {
+ ALOGW("native_window_dequeue_buffer_and_wait returned error %d", err);
return;
}
- CHECK_EQ(0, mSurface->ANativeWindow::lockBuffer(mSurface.get(), mBuf));
-
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
Rect bounds(mWidth, mHeight);
@@ -131,7 +130,7 @@
if (mBuf!= NULL) {
CHECK_EQ(0, mapper.unlock(mBuf->handle));
- if ((err = mSurface->ANativeWindow::queueBuffer(mSurface.get(), mBuf)) != 0) {
+ if ((err = mSurface->ANativeWindow::queueBuffer(mSurface.get(), mBuf, -1)) != 0) {
ALOGW("Surface::queueBuffer returned error %d", err);
}
}
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp
index 5026073..f735c0b 100755
--- a/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp
+++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp
@@ -1483,11 +1483,15 @@
(int32_t*)&(pVideoStreamHandler->m_videoHeight));
(*pStreamHandler) = (M4_StreamHandler*)(pVideoStreamHandler);
- meta->findInt64(kKeyDuration,
- (int64_t*)&(Duration));
- ((*pStreamHandler)->m_duration) =
- (int32_t)((Duration)/1000); // conversion to mS
+ meta->findInt64(kKeyDuration, (int64_t*)&(Duration));
+ ((*pStreamHandler)->m_duration) = (int32_t)((Duration)/1000); // conversion to mS
pC->mMaxDuration = ((*pStreamHandler)->m_duration);
+ if (pC->mMaxDuration == 0) {
+ ALOGE("Video is too short: %lld Us", Duration);
+ delete pVideoStreamHandler;
+ pVideoStreamHandler = NULL;
+ return M4ERR_PARAMETER;
+ }
ALOGV("VideoEditor3gpReader_getNextStreamHandler m_duration %d",
(*pStreamHandler)->m_duration);
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 0562f8e..f8813c9 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -18,29 +18,19 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "AudioRecord"
-#include <stdint.h>
+#include <sys/resource.h>
#include <sys/types.h>
-#include <sched.h>
-#include <sys/resource.h>
+#include <binder/IPCThreadState.h>
+#include <cutils/atomic.h>
+#include <cutils/compiler.h>
+#include <media/AudioRecord.h>
+#include <media/AudioSystem.h>
+#include <system/audio.h>
+#include <utils/Log.h>
#include <private/media/AudioTrackShared.h>
-#include <media/AudioSystem.h>
-#include <media/AudioRecord.h>
-#include <media/mediarecorder.h>
-
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
-#include <binder/Parcel.h>
-#include <binder/IPCThreadState.h>
-#include <utils/Timers.h>
-#include <utils/Atomic.h>
-
-#include <system/audio.h>
-#include <cutils/bitops.h>
-#include <cutils/compiler.h>
-
namespace android {
// ---------------------------------------------------------------------------
@@ -49,18 +39,18 @@
int* frameCount,
uint32_t sampleRate,
audio_format_t format,
- int channelCount)
+ audio_channel_mask_t channelMask)
{
size_t size = 0;
- if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size)
+ if (AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size)
!= NO_ERROR) {
ALOGE("AudioSystem could not query the input buffer size.");
return NO_INIT;
}
if (size == 0) {
- ALOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d",
- sampleRate, format, channelCount);
+ ALOGE("Unsupported configuration: sampleRate %d, format %d, channelMask %#x",
+ sampleRate, format, channelMask);
return BAD_VALUE;
}
@@ -68,6 +58,7 @@
size <<= 1;
if (audio_is_linear_pcm(format)) {
+ int channelCount = popcount(channelMask);
size /= channelCount * audio_bytes_per_sample(format);
}
@@ -87,9 +78,8 @@
audio_source_t inputSource,
uint32_t sampleRate,
audio_format_t format,
- uint32_t channelMask,
+ audio_channel_mask_t channelMask,
int frameCount,
- record_flags flags,
callback_t cbf,
void* user,
int notificationFrames,
@@ -98,7 +88,7 @@
mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
{
mStatus = set(inputSource, sampleRate, format, channelMask,
- frameCount, flags, cbf, user, notificationFrames, sessionId);
+ frameCount, cbf, user, notificationFrames, sessionId);
}
AudioRecord::~AudioRecord()
@@ -122,9 +112,8 @@
audio_source_t inputSource,
uint32_t sampleRate,
audio_format_t format,
- uint32_t channelMask,
+ audio_channel_mask_t channelMask,
int frameCount,
- record_flags flags,
callback_t cbf,
void* user,
int notificationFrames,
@@ -132,7 +121,7 @@
int sessionId)
{
- ALOGV("set(): sampleRate %d, channelMask %d, frameCount %d",sampleRate, channelMask, frameCount);
+ ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask, frameCount);
AutoMutex lock(mLock);
@@ -174,7 +163,6 @@
sampleRate,
format,
channelMask,
- (audio_in_acoustics_t)flags,
mSessionId);
if (input == 0) {
ALOGE("Could not get audio input for record source %d", inputSource);
@@ -229,7 +217,6 @@
mNewPosition = 0;
mUpdatePeriod = 0;
mInputSource = inputSource;
- mFlags = flags;
mInput = input;
AudioSystem::acquireAudioSessionId(mSessionId);
@@ -457,7 +444,7 @@
status_t AudioRecord::openRecord_l(
uint32_t sampleRate,
audio_format_t format,
- uint32_t channelMask,
+ audio_channel_mask_t channelMask,
int frameCount,
audio_io_handle_t input)
{
@@ -613,7 +600,6 @@
mCblk->sampleRate,
mFormat,
mChannelMask,
- (audio_in_acoustics_t)mFlags,
mSessionId);
return mInput;
}
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 4c41ba5..9c270c8 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -41,7 +41,7 @@
// Cached values for recording queries, all protected by gLock
uint32_t AudioSystem::gPrevInSamplingRate = 16000;
audio_format_t AudioSystem::gPrevInFormat = AUDIO_FORMAT_PCM_16_BIT;
-int AudioSystem::gPrevInChannelCount = 1;
+audio_channel_mask_t AudioSystem::gPrevInChannelMask = AUDIO_CHANNEL_IN_MONO;
size_t AudioSystem::gInBuffSize = 0;
@@ -334,25 +334,25 @@
return NO_ERROR;
}
-status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount,
- size_t* buffSize)
+status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask, size_t* buffSize)
{
gLock.lock();
// Do we have a stale gInBufferSize or are we requesting the input buffer size for new values
size_t inBuffSize = gInBuffSize;
if ((inBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat)
- || (channelCount != gPrevInChannelCount)) {
+ || (channelMask != gPrevInChannelMask)) {
gLock.unlock();
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) {
return PERMISSION_DENIED;
}
- inBuffSize = af->getInputBufferSize(sampleRate, format, channelCount);
+ inBuffSize = af->getInputBufferSize(sampleRate, format, channelMask);
gLock.lock();
// save the request params
gPrevInSamplingRate = sampleRate;
gPrevInFormat = format;
- gPrevInChannelCount = channelCount;
+ gPrevInChannelMask = channelMask;
gInBuffSize = inBuffSize;
}
@@ -625,12 +625,11 @@
uint32_t samplingRate,
audio_format_t format,
uint32_t channels,
- audio_in_acoustics_t acoustics,
int sessionId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
- return aps->getInput(inputSource, samplingRate, format, channels, acoustics, sessionId);
+ return aps->getInput(inputSource, samplingRate, format, channels, sessionId);
}
status_t AudioSystem::startInput(audio_io_handle_t input)
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index e8dd438..27f6b45 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -32,7 +32,7 @@
CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
OPEN_RECORD,
SAMPLE_RATE,
- CHANNEL_COUNT,
+ CHANNEL_COUNT, // obsolete
FORMAT,
FRAME_COUNT,
LATENCY,
@@ -86,7 +86,7 @@
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
- uint32_t channelMask,
+ audio_channel_mask_t channelMask,
int frameCount,
track_flags_t flags,
const sp<IMemory>& sharedBuffer,
@@ -182,6 +182,7 @@
return reply.readInt32();
}
+#if 0
virtual int channelCount(audio_io_handle_t output) const
{
Parcel data, reply;
@@ -190,6 +191,7 @@
remote()->transact(CHANNEL_COUNT, data, &reply);
return reply.readInt32();
}
+#endif
virtual audio_format_t format(audio_io_handle_t output) const
{
@@ -347,13 +349,14 @@
remote()->transact(REGISTER_CLIENT, data, &reply);
}
- virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const
+ virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask) const
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
data.writeInt32(sampleRate);
data.writeInt32(format);
- data.writeInt32(channelCount);
+ data.writeInt32(channelMask);
remote()->transact(GET_INPUTBUFFERSIZE, data, &reply);
return reply.readInt32();
}
@@ -698,7 +701,7 @@
int streamType = data.readInt32();
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
- int channelCount = data.readInt32();
+ audio_channel_mask_t channelMask = data.readInt32();
size_t bufferCount = data.readInt32();
track_flags_t flags = (track_flags_t) data.readInt32();
sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
@@ -708,7 +711,7 @@
status_t status;
sp<IAudioTrack> track = createTrack(pid,
(audio_stream_type_t) streamType, sampleRate, format,
- channelCount, bufferCount, flags, buffer, output, tid, &sessionId, &status);
+ channelMask, bufferCount, flags, buffer, output, tid, &sessionId, &status);
reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(track->asBinder());
@@ -720,13 +723,13 @@
audio_io_handle_t input = (audio_io_handle_t) data.readInt32();
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
- int channelCount = data.readInt32();
+ audio_channel_mask_t channelMask = data.readInt32();
size_t bufferCount = data.readInt32();
track_flags_t flags = (track_flags_t) data.readInt32();
int sessionId = data.readInt32();
status_t status;
sp<IAudioRecord> record = openRecord(pid, input,
- sampleRate, format, channelCount, bufferCount, flags, &sessionId, &status);
+ sampleRate, format, channelMask, bufferCount, flags, &sessionId, &status);
reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(record->asBinder());
@@ -737,11 +740,13 @@
reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
return NO_ERROR;
} break;
+#if 0
case CHANNEL_COUNT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
reply->writeInt32( channelCount((audio_io_handle_t) data.readInt32()) );
return NO_ERROR;
} break;
+#endif
case FORMAT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
@@ -846,8 +851,8 @@
CHECK_INTERFACE(IAudioFlinger, data, reply);
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
- int channelCount = data.readInt32();
- reply->writeInt32( getInputBufferSize(sampleRate, format, channelCount) );
+ audio_channel_mask_t channelMask = data.readInt32();
+ reply->writeInt32( getInputBufferSize(sampleRate, format, channelMask) );
return NO_ERROR;
} break;
case OPEN_OUTPUT: {
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 7aab8d6..5a4512e 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -176,7 +176,6 @@
uint32_t samplingRate,
audio_format_t format,
uint32_t channels,
- audio_in_acoustics_t acoustics,
int audioSession)
{
Parcel data, reply;
@@ -185,7 +184,6 @@
data.writeInt32(samplingRate);
data.writeInt32(static_cast <uint32_t>(format));
data.writeInt32(channels);
- data.writeInt32(static_cast <uint32_t>(acoustics));
data.writeInt32(audioSession);
remote()->transact(GET_INPUT, data, &reply);
return static_cast <audio_io_handle_t> (reply.readInt32());
@@ -465,14 +463,11 @@
uint32_t samplingRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
uint32_t channels = data.readInt32();
- audio_in_acoustics_t acoustics =
- static_cast <audio_in_acoustics_t>(data.readInt32());
int audioSession = data.readInt32();
audio_io_handle_t input = getInput(inputSource,
samplingRate,
format,
channels,
- acoustics,
audioSession);
reply->writeInt32(static_cast <int>(input));
return NO_ERROR;
diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp
index 284ba01..33b7bd5 100644
--- a/media/libstagefright/AACWriter.cpp
+++ b/media/libstagefright/AACWriter.cpp
@@ -28,6 +28,8 @@
#include <media/stagefright/MetaData.h>
#include <media/mediarecorder.h>
#include <sys/prctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <fcntl.h>
namespace android {
@@ -44,7 +46,7 @@
ALOGV("AACWriter Constructor");
- mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
+ mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
if (mFd >= 0) {
mInitCheck = OK;
}
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index c4743a1..b4894e9 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -595,7 +595,7 @@
// Dequeue buffers and send them to OMX
for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
ANativeWindowBuffer *buf;
- err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
+ err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
if (err != 0) {
ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
break;
@@ -653,7 +653,7 @@
mComponentName.c_str(), info->mBufferID);
int err = mNativeWindow->cancelBuffer(
- mNativeWindow.get(), info->mGraphicBuffer.get());
+ mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
CHECK_EQ(err, 0);
@@ -664,7 +664,8 @@
ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
ANativeWindowBuffer *buf;
- if (mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf) != 0) {
+ int fenceFd = -1;
+ if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
ALOGE("dequeueBuffer failed.");
return NULL;
}
@@ -2188,7 +2189,8 @@
// on the screen and then been replaced, so an previous video frames are
// guaranteed NOT to be currently displayed.
for (int i = 0; i < numBufs + 1; i++) {
- err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb);
+ int fenceFd = -1;
+ err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
if (err != NO_ERROR) {
ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
strerror(-err), -err);
@@ -2196,13 +2198,6 @@
}
sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- err = mNativeWindow->lockBuffer(mNativeWindow.get(),
- buf->getNativeBuffer());
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: lockBuffer failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
// Fill the buffer with the a 1x1 checkerboard pattern ;)
uint32_t* img = NULL;
@@ -2223,7 +2218,7 @@
}
err = mNativeWindow->queueBuffer(mNativeWindow.get(),
- buf->getNativeBuffer());
+ buf->getNativeBuffer(), -1);
if (err != NO_ERROR) {
ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
strerror(-err), -err);
@@ -2238,7 +2233,7 @@
if (err != NO_ERROR) {
// Clean up after an error.
if (anb != NULL) {
- mNativeWindow->cancelBuffer(mNativeWindow.get(), anb);
+ mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
}
native_window_api_disconnect(mNativeWindow.get(),
@@ -2751,7 +2746,7 @@
status_t err;
if ((err = mCodec->mNativeWindow->queueBuffer(
mCodec->mNativeWindow.get(),
- info->mGraphicBuffer.get())) == OK) {
+ info->mGraphicBuffer.get(), -1)) == OK) {
info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
} else {
mCodec->signalError(OMX_ErrorUndefined, err);
@@ -3253,11 +3248,6 @@
if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
continue;
}
-
- status_t err = mCodec->mNativeWindow->lockBuffer(
- mCodec->mNativeWindow.get(),
- info->mGraphicBuffer.get());
- CHECK_EQ(err, (status_t)OK);
} else {
CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
}
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index ca85640..15a7143 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -36,7 +36,7 @@
mPaused(false),
mResumed(false) {
- mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
+ mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
if (mFd >= 0) {
mInitCheck = OK;
}
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 8a68036..e5b4d75 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -81,6 +81,7 @@
libssl \
libstagefright_omx \
libstagefright_yuv \
+ libsync \
libui \
libutils \
libvorbisidec \
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 72d797e..ed142a4 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -48,7 +48,8 @@
AudioSource::AudioSource(
audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount)
- : mStarted(false),
+ : mRecord(NULL),
+ mStarted(false),
mSampleRate(sampleRate),
mPrevSampleTimeUs(0),
mNumFramesReceived(0),
@@ -61,7 +62,7 @@
status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
sampleRate,
AUDIO_FORMAT_PCM_16_BIT,
- channelCount);
+ audio_channel_in_mask_from_count(channelCount));
if (status == OK) {
// make sure that the AudioRecord callback never returns more than the maximum
// buffer size
@@ -73,15 +74,10 @@
bufCount++;
}
- AudioRecord::record_flags flags = (AudioRecord::record_flags)
- (AudioRecord::RECORD_AGC_ENABLE |
- AudioRecord::RECORD_NS_ENABLE |
- AudioRecord::RECORD_IIR_ENABLE);
mRecord = new AudioRecord(
inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
audio_channel_in_mask_from_count(channelCount),
bufCount * frameCount,
- flags,
AudioRecordCallbackFunction,
this,
frameCount);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 0f346d8..2c68075 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -130,7 +130,7 @@
CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
native_window_set_buffers_timestamp(mNativeWindow.get(), timeUs * 1000);
status_t err = mNativeWindow->queueBuffer(
- mNativeWindow.get(), buffer->graphicBuffer().get());
+ mNativeWindow.get(), buffer->graphicBuffer().get(), -1);
if (err != 0) {
ALOGE("queueBuffer failed with error %s (%d)", strerror(-err),
-err);
diff --git a/media/libstagefright/FLACExtractor.cpp b/media/libstagefright/FLACExtractor.cpp
index 668d7f7..29bb056 100644
--- a/media/libstagefright/FLACExtractor.cpp
+++ b/media/libstagefright/FLACExtractor.cpp
@@ -350,7 +350,7 @@
for (FLAC__uint32 i = 0; i < vc->num_comments; ++i) {
FLAC__StreamMetadata_VorbisComment_Entry *vce;
vce = &vc->comments[i];
- if (mFileMetadata != 0) {
+ if (mFileMetadata != 0 && vce->entry != NULL) {
parseVorbisComment(mFileMetadata, (const char *) vce->entry,
vce->length);
}
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 755b502..cc18a1d 100755
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -269,7 +269,7 @@
mAreGeoTagsAvailable(false),
mStartTimeOffsetMs(-1) {
- mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
+ mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
if (mFd >= 0) {
mInitCheck = OK;
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index fde7ebf..1d4ab32 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1776,7 +1776,7 @@
// Dequeue buffers and send them to OMX
for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
ANativeWindowBuffer* buf;
- err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
+ err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
if (err != 0) {
ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
break;
@@ -1832,7 +1832,7 @@
CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer);
int err = mNativeWindow->cancelBuffer(
- mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get());
+ mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get(), -1);
if (err != 0) {
CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err);
@@ -1846,7 +1846,8 @@
OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() {
// Dequeue the next buffer from the native window.
ANativeWindowBuffer* buf;
- int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
+ int fenceFd = -1;
+ int err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
if (err != 0) {
CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err);
@@ -1950,7 +1951,8 @@
// on the screen and then been replaced, so an previous video frames are
// guaranteed NOT to be currently displayed.
for (int i = 0; i < numBufs + 1; i++) {
- err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb);
+ int fenceFd = -1;
+ err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
if (err != NO_ERROR) {
ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
strerror(-err), -err);
@@ -1958,13 +1960,6 @@
}
sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- err = mNativeWindow->lockBuffer(mNativeWindow.get(),
- buf->getNativeBuffer());
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: lockBuffer failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
// Fill the buffer with the a 1x1 checkerboard pattern ;)
uint32_t* img = NULL;
@@ -1985,7 +1980,7 @@
}
err = mNativeWindow->queueBuffer(mNativeWindow.get(),
- buf->getNativeBuffer());
+ buf->getNativeBuffer(), -1);
if (err != NO_ERROR) {
ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
strerror(-err), -err);
@@ -2000,7 +1995,7 @@
if (err != NO_ERROR) {
// Clean up after an error.
if (anb != NULL) {
- mNativeWindow->cancelBuffer(mNativeWindow.get(), anb);
+ mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
}
native_window_api_disconnect(mNativeWindow.get(),
@@ -3199,23 +3194,6 @@
return;
}
- if (info->mMediaBuffer != NULL) {
- sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
- if (graphicBuffer != 0) {
- // When using a native buffer we need to lock the buffer before
- // giving it to OMX.
- CODEC_LOGV("Calling lockBuffer on %p", info->mBuffer);
- int err = mNativeWindow->lockBuffer(mNativeWindow.get(),
- graphicBuffer.get());
- if (err != 0) {
- CODEC_LOGE("lockBuffer failed w/ error 0x%08x", err);
-
- setState(ERROR);
- return;
- }
- }
- }
-
CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer);
status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 5d72a05..f1f444e 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -96,11 +96,6 @@
mFrameAvailableListener = listener;
}
-sp<GraphicBuffer> SurfaceMediaSource::getCurrentBuffer() const {
- Mutex::Autolock lock(mMutex);
- return mCurrentBuf;
-}
-
void SurfaceMediaSource::dump(String8& result) const
{
char buffer[1024];
@@ -185,6 +180,35 @@
return meta;
}
+// Pass the data to the MediaBuffer. Pass in only the metadata
+// The metadata passed consists of two parts:
+// 1. First, there is an integer indicating that it is a GRAlloc
+// source (kMetadataBufferTypeGrallocSource)
+// 2. This is followed by the buffer_handle_t that is a handle to the
+// GRalloc buffer. The encoder needs to interpret this GRalloc handle
+// and encode the frames.
+// --------------------------------------------------------------
+// | kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
+// --------------------------------------------------------------
+// Note: Call only when you have the lock
+static void passMetadataBuffer(MediaBuffer **buffer,
+ buffer_handle_t bufferHandle) {
+ // MediaBuffer allocates and owns this data
+ MediaBuffer *tempBuffer = new MediaBuffer(4 + sizeof(buffer_handle_t));
+ char *data = (char *)tempBuffer->data();
+ if (data == NULL) {
+ ALOGE("Cannot allocate memory for metadata buffer!");
+ return;
+ }
+ OMX_U32 type = kMetadataBufferTypeGrallocSource;
+ memcpy(data, &type, 4);
+ memcpy(data + 4, &bufferHandle, sizeof(buffer_handle_t));
+ *buffer = tempBuffer;
+
+ ALOGV("handle = %p, , offset = %d, length = %d",
+ bufferHandle, (*buffer)->range_length(), (*buffer)->range_offset());
+}
+
status_t SurfaceMediaSource::read( MediaBuffer **buffer,
const ReadOptions *options)
{
@@ -220,7 +244,8 @@
if (mStartTimeNs > 0) {
if (item.mTimestamp < mStartTimeNs) {
// This frame predates start of record, discard
- mBufferQueue->releaseBuffer(item.mBuf, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
+ mBufferQueue->releaseBuffer(item.mBuf, EGL_NO_DISPLAY,
+ EGL_NO_SYNC_KHR, Fence::NO_FENCE);
continue;
}
mStartTimeNs = item.mTimestamp - mStartTimeNs;
@@ -251,13 +276,14 @@
if (item.mGraphicBuffer != NULL) {
mBufferSlot[mCurrentSlot] = item.mGraphicBuffer;
}
- mCurrentBuf = mBufferSlot[mCurrentSlot];
+
+ mCurrentBuffers.push_back(mBufferSlot[mCurrentSlot]);
int64_t prevTimeStamp = mCurrentTimestamp;
mCurrentTimestamp = item.mTimestamp;
mNumFramesEncoded++;
// Pass the data to the MediaBuffer. Pass in only the metadata
- passMetadataBufferLocked(buffer);
+ passMetadataBuffer(buffer, mBufferSlot[mCurrentSlot]->handle);
(*buffer)->setObserver(this);
(*buffer)->add_ref();
@@ -270,34 +296,12 @@
return OK;
}
-// Pass the data to the MediaBuffer. Pass in only the metadata
-// The metadata passed consists of two parts:
-// 1. First, there is an integer indicating that it is a GRAlloc
-// source (kMetadataBufferTypeGrallocSource)
-// 2. This is followed by the buffer_handle_t that is a handle to the
-// GRalloc buffer. The encoder needs to interpret this GRalloc handle
-// and encode the frames.
-// --------------------------------------------------------------
-// | kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
-// --------------------------------------------------------------
-// Note: Call only when you have the lock
-void SurfaceMediaSource::passMetadataBufferLocked(MediaBuffer **buffer) {
- ALOGV("passMetadataBuffer");
- // MediaBuffer allocates and owns this data
- MediaBuffer *tempBuffer =
- new MediaBuffer(4 + sizeof(buffer_handle_t));
- char *data = (char *)tempBuffer->data();
- if (data == NULL) {
- ALOGE("Cannot allocate memory for metadata buffer!");
- return;
- }
- OMX_U32 type = kMetadataBufferTypeGrallocSource;
- memcpy(data, &type, 4);
- memcpy(data + 4, &(mCurrentBuf->handle), sizeof(buffer_handle_t));
- *buffer = tempBuffer;
-
- ALOGV("handle = %p, , offset = %d, length = %d",
- mCurrentBuf->handle, (*buffer)->range_length(), (*buffer)->range_offset());
+static buffer_handle_t getMediaBufferHandle(MediaBuffer *buffer) {
+ // need to convert to char* for pointer arithmetic and then
+ // copy the byte stream into our handle
+ buffer_handle_t bufferHandle;
+ memcpy(&bufferHandle, (char*)(buffer->data()) + 4, sizeof(buffer_handle_t));
+ return bufferHandle;
}
void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
@@ -307,20 +311,31 @@
Mutex::Autolock lock(mMutex);
- if (mStopped) {
- ALOGV("signalBufferReturned: mStopped = true! Nothing to do!");
- return;
+ buffer_handle_t bufferHandle = getMediaBufferHandle(buffer);
+
+ for (size_t i = 0; i < mCurrentBuffers.size(); i++) {
+ if (mCurrentBuffers[i]->handle == bufferHandle) {
+ mCurrentBuffers.removeAt(i);
+ foundBuffer = true;
+ break;
+ }
+ }
+
+ if (!foundBuffer) {
+ ALOGW("returned buffer was not found in the current buffer list");
}
for (int id = 0; id < BufferQueue::NUM_BUFFER_SLOTS; id++) {
if (mBufferSlot[id] == NULL) {
continue;
}
- if (checkBufferMatchesSlot(id, buffer)) {
+
+ if (bufferHandle == mBufferSlot[id]->handle) {
ALOGV("Slot %d returned, matches handle = %p", id,
mBufferSlot[id]->handle);
- mBufferQueue->releaseBuffer(id, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
+ mBufferQueue->releaseBuffer(id, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
+ Fence::NO_FENCE);
buffer->setObserver(0);
buffer->release();
@@ -335,15 +350,6 @@
}
}
-bool SurfaceMediaSource::checkBufferMatchesSlot(int slot, MediaBuffer *buffer) {
- ALOGV("Check if Buffer matches slot");
- // need to convert to char* for pointer arithmetic and then
- // copy the byte stream into our handle
- buffer_handle_t bufferHandle ;
- memcpy( &bufferHandle, (char *)(buffer->data()) + 4, sizeof(buffer_handle_t));
- return mBufferSlot[slot]->handle == bufferHandle;
-}
-
// Part of the BufferQueue::ConsumerListener
void SurfaceMediaSource::onFrameAvailable() {
ALOGV("onFrameAvailable");
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 8673bad..2704a37 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -141,13 +141,12 @@
const void *data, size_t size, void *platformPrivate) {
ANativeWindowBuffer *buf;
int err;
- if ((err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf)) != 0) {
+ if ((err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(),
+ &buf)) != 0) {
ALOGW("Surface::dequeueBuffer returned error %d", err);
return;
}
- CHECK_EQ(0, mNativeWindow->lockBuffer(mNativeWindow.get(), buf));
-
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
Rect bounds(mCropWidth, mCropHeight);
@@ -231,7 +230,8 @@
CHECK_EQ(0, mapper.unlock(buf->handle));
- if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf)) != 0) {
+ if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf,
+ -1)) != 0) {
ALOGW("Surface::queueBuffer returned error %d", err);
}
buf = NULL;
diff --git a/media/libstagefright/tests/Android.mk b/media/libstagefright/tests/Android.mk
index a1e6be7..57fff0b 100644
--- a/media/libstagefright/tests/Android.mk
+++ b/media/libstagefright/tests/Android.mk
@@ -20,9 +20,10 @@
libgui \
libmedia \
libstagefright \
- libstagefright_omx \
libstagefright_foundation \
+ libstagefright_omx \
libstlport \
+ libsync \
libui \
libutils \
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index 466f521..cc2aca7 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -509,31 +509,31 @@
// cpu YV12 buffer
void SurfaceMediaSourceTest::oneBufferPass(int width, int height ) {
ANativeWindowBuffer* anb;
- ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+ ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
ASSERT_TRUE(anb != NULL);
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
// Fill the buffer with the a checkerboard pattern
uint8_t* img = NULL;
+ sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
SurfaceMediaSourceTest::fillYV12Buffer(img, width, height, buf->getStride());
buf->unlock();
- ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+ ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
+ -1));
}
// Dequeuing and queuing the buffer without really filling it in.
void SurfaceMediaSourceTest::oneBufferPassNoFill(int width, int height ) {
ANativeWindowBuffer* anb;
- ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+ ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
ASSERT_TRUE(anb != NULL);
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- // ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
// We do not fill the buffer in. Just queue it back.
- ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+ sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+ ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
+ -1));
}
// Fill a YV12 buffer with a multi-colored checkerboard pattern
@@ -652,7 +652,7 @@
ANativeWindowBuffer* anb;
// Note: make sure we get an ERROR back when dequeuing!
- ASSERT_NE(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+ ASSERT_NE(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
}
// pass multiple buffers from the native_window the SurfaceMediaSource
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index bf7795c..d672dff 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -667,7 +667,7 @@
// reads the object's data and writes it to the specified file path
bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int group, int perm) {
ALOGD("readObject: %s", destPath);
- int fd = ::open(destPath, O_RDWR | O_CREAT | O_TRUNC);
+ int fd = ::open(destPath, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd < 0) {
ALOGE("open failed for %s", destPath);
return false;
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 5606187..662a93d 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -931,7 +931,7 @@
initialData = ret - MTP_CONTAINER_HEADER_SIZE;
mtp_file_range mfr;
- mfr.fd = open(mSendObjectFilePath, O_RDWR | O_CREAT | O_TRUNC);
+ mfr.fd = open(mSendObjectFilePath, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (mfr.fd < 0) {
result = MTP_RESPONSE_GENERAL_ERROR;
goto done;
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 8473fab..c2d2790 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -89,7 +89,7 @@
LOCAL_CFLAGS += -DSTATE_QUEUE_INSTANTIATIONS='"StateQueueInstantiations.cpp"'
-LOCAL_CFLAGS += -DHAVE_REQUEST_PRIORITY -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE -USOAKER
+LOCAL_CFLAGS += -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
# uncomment for systrace
# LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_AUDIO
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index b78c6d1..ceaf27d 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -83,13 +83,7 @@
#include "PipeReader.h"
#include "SourceAudioBufferProvider.h"
-#ifdef HAVE_REQUEST_PRIORITY
#include "SchedulingPolicyService.h"
-#endif
-
-#ifdef SOAKER
-#include "Soaker.h"
-#endif
// ----------------------------------------------------------------------------
@@ -908,7 +902,7 @@
{
Mutex::Autolock _l(mLock);
thread = checkPlaybackThread_l(ioHandle);
- if (thread == NULL) {
+ if (thread == 0) {
thread = checkRecordThread_l(ioHandle);
} else if (thread == primaryPlaybackThread_l()) {
// indicate output device change to all input threads for pre processing
@@ -964,7 +958,8 @@
return String8("");
}
-size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const
+size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask) const
{
status_t ret = initCheck();
if (ret != NO_ERROR) {
@@ -975,7 +970,7 @@
mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
struct audio_config config = {
sample_rate: sampleRate,
- channel_mask: audio_channel_in_mask_from_count(channelCount),
+ channel_mask: channelMask,
format: format,
};
size_t size = mPrimaryHardwareDev->get_input_buffer_size(mPrimaryHardwareDev, &config);
@@ -1106,6 +1101,20 @@
mClients.removeItem(pid);
}
+// getEffectThread_l() must be called with AudioFlinger::mLock held
+sp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(int sessionId, int EffectId)
+{
+ sp<PlaybackThread> thread;
+
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, EffectId) != 0) {
+ ALOG_ASSERT(thread == 0);
+ thread = mPlaybackThreads.valueAt(i);
+ }
+ }
+
+ return thread;
+}
// ----------------------------------------------------------------------------
@@ -1118,8 +1127,7 @@
mChannelCount(0),
mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),
mParamStatus(NO_ERROR),
- mStandby(false), mId(id),
- mDevice(device),
+ mStandby(false), mDevice((audio_devices_t) device), mId(id),
mDeathRecipient(new PMDeathRecipient(this))
{
}
@@ -1775,7 +1783,7 @@
track = TimedTrack::create(this, client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, sessionId);
}
- if (track == NULL || track->getCblk() == NULL || track->name() < 0) {
+ if (track == 0 || track->getCblk() == NULL || track->name() < 0) {
lStatus = NO_MEMORY;
goto Exit;
}
@@ -1790,7 +1798,6 @@
}
}
-#ifdef HAVE_REQUEST_PRIORITY
if ((flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
pid_t callingPid = IPCThreadState::self()->getCallingPid();
// we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful,
@@ -1801,7 +1808,6 @@
1, callingPid, tid, err);
}
}
-#endif
lStatus = NO_ERROR;
@@ -2181,9 +2187,6 @@
audio_io_handle_t id, uint32_t device, type_t type)
: PlaybackThread(audioFlinger, output, id, device, type),
// mAudioMixer below
-#ifdef SOAKER
- mSoaker(NULL),
-#endif
// mFastMixer below
mFastMixerFutex(0)
// mOutputSink below
@@ -2253,13 +2256,6 @@
mTeeSource = teeSource;
#endif
-#ifdef SOAKER
- // create a soaker as workaround for governor issues
- mSoaker = new Soaker();
- // FIXME Soaker should only run when needed, i.e. when FastMixer is not in COLD_IDLE
- mSoaker->run("Soaker", PRIORITY_LOWEST);
-#endif
-
// create fast mixer and configure it initially with just one fast track for our submix
mFastMixer = new FastMixer();
FastMixerStateQueue *sq = mFastMixer->sq();
@@ -2291,14 +2287,12 @@
// start the fast mixer
mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO);
-#ifdef HAVE_REQUEST_PRIORITY
pid_t tid = mFastMixer->getTid();
int err = requestPriority(getpid_cached, tid, 2);
if (err != 0) {
ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
2, getpid_cached, tid, err);
}
-#endif
#ifdef AUDIO_WATCHDOG
// create and start the watchdog
@@ -2356,12 +2350,6 @@
delete fastTrack->mBufferProvider;
sq->end(false /*didModify*/);
delete mFastMixer;
-#ifdef SOAKER
- if (mSoaker != NULL) {
- mSoaker->requestExitAndWait();
- }
- delete mSoaker;
-#endif
if (mAudioWatchdog != 0) {
mAudioWatchdog->requestExit();
mAudioWatchdog->requestExitAndWait();
@@ -2494,9 +2482,6 @@
// MIXER
nsecs_t lastWarning = 0;
-if (mType == MIXER) {
- longStandbyExit = false;
-}
// DUPLICATING
// FIXME could this be made local to while loop?
@@ -2621,11 +2606,6 @@
ns2ms(delta), mNumDelayedWrites, this);
lastWarning = now;
}
- // FIXME this is broken: longStandbyExit should be handled out of the if() and with
- // a different threshold. Or completely removed for what it is worth anyway...
- if (mStandby) {
- longStandbyExit = true;
- }
}
}
@@ -2833,11 +2813,10 @@
} else {
sleepTime = idleSleepTime;
}
- } else if (mBytesWritten != 0 ||
- (mMixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)) {
+ } else if (mBytesWritten != 0 || (mMixerStatus == MIXER_TRACKS_ENABLED)) {
memset (mMixBuffer, 0, mixBufferSize);
sleepTime = 0;
- ALOGV_IF((mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start");
+ ALOGV_IF((mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED)), "anticipated start");
}
// TODO add standby time extension fct of effect tail
}
@@ -3359,7 +3338,7 @@
idleSleepTime = idleSleepTimeUs();
}
-void AudioFlinger::MixerThread::invalidateTracks(audio_stream_type_t streamType)
+void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
{
ALOGV ("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d",
this, streamType, mTracks.size());
@@ -3468,7 +3447,7 @@
// forward device change to effects that have requested to be
// aware of attached audio device.
- mDevice = (uint32_t)value;
+ mDevice = (audio_devices_t) value;
for (size_t i = 0; i < mEffectChains.size(); i++) {
mEffectChains[i]->setDevice_l(mDevice);
}
@@ -3588,7 +3567,7 @@
}
break;
}
- ALOG_ASSERT(actual <= count);
+ ALOG_ASSERT(actual <= (ssize_t)count);
write(teeFd, buffer, actual * channelCount * sizeof(short));
total += actual;
}
@@ -4056,6 +4035,7 @@
return false;
}
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ // see note at standby() declaration
if (playbackThread->standby() && !playbackThread->isSuspended()) {
ALOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(), thread.get());
return false;
@@ -4677,6 +4657,44 @@
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ sp<AudioFlinger> af = mClient->audioFlinger();
+
+ Mutex::Autolock _l(af->mLock);
+
+ sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
+
+ if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) {
+ Mutex::Autolock _dl(playbackThread->mLock);
+ Mutex::Autolock _sl(srcThread->mLock);
+ sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
+ if (chain == 0) {
+ return INVALID_OPERATION;
+ }
+
+ sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
+ if (effect == 0) {
+ return INVALID_OPERATION;
+ }
+ srcThread->removeEffect_l(effect);
+ playbackThread->addEffect_l(effect);
+ // removeEffect_l() has stopped the effect if it was active so it must be restarted
+ if (effect->state() == EffectModule::ACTIVE ||
+ effect->state() == EffectModule::STOPPING) {
+ effect->start();
+ }
+
+ sp<EffectChain> dstChain = effect->chain().promote();
+ if (dstChain == 0) {
+ srcThread->addEffect_l(effect);
+ return INVALID_OPERATION;
+ }
+ AudioSystem::unregisterEffect(effect->id());
+ AudioSystem::registerEffect(&effect->desc(),
+ srcThread->id(),
+ dstChain->strategy(),
+ AUDIO_SESSION_OUTPUT_MIX,
+ effect->id());
+ }
status = playbackThread->attachAuxEffect(this, EffectId);
}
return status;
@@ -4774,7 +4792,7 @@
const sp<IMemory>& sharedBuffer,
int sessionId) {
if (!client->reserveTimedTrack())
- return NULL;
+ return 0;
return new TimedTrack(
thread, client, streamType, sampleRate, format, channelMask, frameCount,
@@ -5009,7 +5027,7 @@
AudioBufferProvider::Buffer* buffer, int64_t pts)
{
if (pts == AudioBufferProvider::kInvalidPTS) {
- buffer->raw = 0;
+ buffer->raw = NULL;
buffer->frameCount = 0;
mTimedAudioOutputOnTime = false;
return INVALID_OPERATION;
@@ -5024,7 +5042,7 @@
// if we have no timed buffers, then fail
if (mTimedBufferQueue.isEmpty()) {
- buffer->raw = 0;
+ buffer->raw = NULL;
buffer->frameCount = 0;
return NOT_ENOUGH_DATA;
}
@@ -5051,7 +5069,7 @@
// the transform failed. this shouldn't happen, but if it does
// then just drop this buffer
ALOGW("timedGetNextBuffer transform failed");
- buffer->raw = 0;
+ buffer->raw = NULL;
buffer->frameCount = 0;
trimTimedBufferQueueHead_l("getNextBuffer; no transform");
return NO_ERROR;
@@ -5060,7 +5078,7 @@
if (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME) {
if (OK != mCCHelper.commonTimeToLocalTime(transformedPTS,
&headLocalPTS)) {
- buffer->raw = 0;
+ buffer->raw = NULL;
buffer->frameCount = 0;
return INVALID_OPERATION;
}
@@ -6456,11 +6474,12 @@
// store input device and output device but do not forward output device to audio HAL.
// Note that status is ignored by the caller for output device
// (see AudioFlinger::setParameters()
+ uint32_t /*audio_devices_t*/ newDevice = mDevice;
if (value & AUDIO_DEVICE_OUT_ALL) {
- mDevice &= (uint32_t)~(value & AUDIO_DEVICE_OUT_ALL);
+ newDevice &= (uint32_t)~(value & AUDIO_DEVICE_OUT_ALL);
status = BAD_VALUE;
} else {
- mDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
+ newDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
// disable AEC and NS if the device is a BT SCO headset supporting those pre processings
if (mTrack != NULL) {
bool suspend = audio_is_bluetooth_sco_device(
@@ -6469,7 +6488,8 @@
setEffectSuspended_l(FX_IID_NS, suspend, mTrack->sessionId());
}
}
- mDevice |= (uint32_t)value;
+ newDevice |= value;
+ mDevice = (audio_devices_t) newDevice; // since mDevice is read by other threads, only write to it once
}
if (status == NO_ERROR) {
status = mInput->stream->common.set_parameters(&mInput->stream->common, keyValuePair.string());
@@ -7002,7 +7022,7 @@
{
Mutex::Autolock _l(mLock);
thread = checkRecordThread_l(input);
- if (thread == NULL) {
+ if (thread == 0) {
return BAD_VALUE;
}
@@ -7026,21 +7046,11 @@
status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output)
{
Mutex::Autolock _l(mLock);
- MixerThread *dstThread = checkMixerThread_l(output);
- if (dstThread == NULL) {
- ALOGW("setStreamOutput() bad output id %d", output);
- return BAD_VALUE;
- }
-
ALOGV("setStreamOutput() stream %d to output %d", stream, output);
- audioConfigChanged_l(AudioSystem::STREAM_CONFIG_CHANGED, output, &stream);
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
- if (thread != dstThread && thread->type() != ThreadBase::DIRECT) {
- MixerThread *srcThread = (MixerThread *)thread;
- srcThread->invalidateTracks(stream);
- }
+ thread->invalidateTracks(stream);
}
return NO_ERROR;
@@ -7134,20 +7144,14 @@
}
}
if (!found) {
+ Mutex::Autolock _l (t->mLock);
// remove all effects from the chain
while (ec->mEffects.size()) {
sp<EffectModule> effect = ec->mEffects[0];
effect->unPin();
- Mutex::Autolock _l (t->mLock);
t->removeEffect_l(effect);
- for (size_t j = 0; j < effect->mHandles.size(); j++) {
- sp<EffectHandle> handle = effect->mHandles[j].promote();
- if (handle != 0) {
- handle->mEffect.clear();
- if (handle->mHasControl && handle->mEnabled) {
- t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
- }
- }
+ if (effect->purgeHandles()) {
+ t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
}
AudioSystem::unregisterEffect(effect->id());
}
@@ -7618,7 +7622,7 @@
}
// create effect handle and connect it to effect module
handle = new EffectHandle(effect, client, effectClient, priority);
- lStatus = effect->addHandle(handle);
+ lStatus = effect->addHandle(handle.get());
if (enabled != NULL) {
*enabled = (int)effect->isEnabled();
}
@@ -7645,6 +7649,12 @@
return handle;
}
+sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect(int sessionId, int effectId)
+{
+ Mutex::Autolock _l(mLock);
+ return getEffect_l(sessionId, effectId);
+}
+
sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(int sessionId, int effectId)
{
sp<EffectChain> chain = getEffectChain_l(sessionId);
@@ -7752,7 +7762,7 @@
}
void AudioFlinger::ThreadBase::disconnectEffect(const sp<EffectModule>& effect,
- const wp<EffectHandle>& handle,
+ EffectHandle *handle,
bool unpinIfLast) {
Mutex::Autolock _l(mLock);
@@ -7944,8 +7954,15 @@
effect_descriptor_t *desc,
int id,
int sessionId)
- : mThread(thread), mChain(chain), mId(id), mSessionId(sessionId), mEffectInterface(NULL),
- mStatus(NO_INIT), mState(IDLE), mSuspended(false)
+ : mPinned(sessionId > AUDIO_SESSION_OUTPUT_MIX),
+ mThread(thread), mChain(chain), mId(id), mSessionId(sessionId),
+ // mDescriptor is set below
+ // mConfig is set by configure() and not used before then
+ mEffectInterface(NULL),
+ mStatus(NO_INIT), mState(IDLE),
+ // mMaxDisableWaitCnt is set by configure() and not used before then
+ // mDisableWaitCnt is set by process() and updateState() and not used before then
+ mSuspended(false)
{
ALOGV("Constructor %p", this);
int lStatus;
@@ -7967,9 +7984,6 @@
goto Error;
}
- if (mSessionId > AUDIO_SESSION_OUTPUT_MIX) {
- mPinned = true;
- }
ALOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface);
return;
Error:
@@ -7997,38 +8011,41 @@
}
}
-status_t AudioFlinger::EffectModule::addHandle(const sp<EffectHandle>& handle)
+status_t AudioFlinger::EffectModule::addHandle(EffectHandle *handle)
{
status_t status;
Mutex::Autolock _l(mLock);
int priority = handle->priority();
size_t size = mHandles.size();
- sp<EffectHandle> h;
+ EffectHandle *controlHandle = NULL;
size_t i;
for (i = 0; i < size; i++) {
- h = mHandles[i].promote();
- if (h == 0) continue;
+ EffectHandle *h = mHandles[i];
+ if (h == NULL || h->destroyed_l()) continue;
+ // first non destroyed handle is considered in control
+ if (controlHandle == NULL)
+ controlHandle = h;
if (h->priority() <= priority) break;
}
// if inserted in first place, move effect control from previous owner to this handle
if (i == 0) {
bool enabled = false;
- if (h != 0) {
- enabled = h->enabled();
- h->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
+ if (controlHandle != NULL) {
+ enabled = controlHandle->enabled();
+ controlHandle->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
}
handle->setControl(true /*hasControl*/, false /*signal*/, enabled /*enabled*/);
status = NO_ERROR;
} else {
status = ALREADY_EXISTS;
}
- ALOGV("addHandle() %p added handle %p in position %d", this, handle.get(), i);
+ ALOGV("addHandle() %p added handle %p in position %d", this, handle, i);
mHandles.insertAt(handle, i);
return status;
}
-size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle)
+size_t AudioFlinger::EffectModule::removeHandle(EffectHandle *handle)
{
Mutex::Autolock _l(mLock);
size_t size = mHandles.size();
@@ -8039,43 +8056,44 @@
if (i == size) {
return size;
}
- ALOGV("removeHandle() %p removed handle %p in position %d", this, handle.unsafe_get(), i);
+ ALOGV("removeHandle() %p removed handle %p in position %d", this, handle, i);
- bool enabled = false;
- EffectHandle *hdl = handle.unsafe_get();
- if (hdl != NULL) {
- ALOGV("removeHandle() unsafe_get OK");
- enabled = hdl->enabled();
- }
mHandles.removeAt(i);
- size = mHandles.size();
// if removed from first place, move effect control from this handle to next in line
- if (i == 0 && size != 0) {
- sp<EffectHandle> h = mHandles[0].promote();
- if (h != 0) {
- h->setControl(true /*hasControl*/, true /*signal*/ , enabled /*enabled*/);
+ if (i == 0) {
+ EffectHandle *h = controlHandle_l();
+ if (h != NULL) {
+ h->setControl(true /*hasControl*/, true /*signal*/ , handle->enabled() /*enabled*/);
}
}
// Prevent calls to process() and other functions on effect interface from now on.
// The effect engine will be released by the destructor when the last strong reference on
// this object is released which can happen after next process is called.
- if (size == 0 && !mPinned) {
+ if (mHandles.size() == 0 && !mPinned) {
mState = DESTROYED;
}
return size;
}
-sp<AudioFlinger::EffectHandle> AudioFlinger::EffectModule::controlHandle()
+// must be called with EffectModule::mLock held
+AudioFlinger::EffectHandle *AudioFlinger::EffectModule::controlHandle_l()
{
- Mutex::Autolock _l(mLock);
- return mHandles.size() != 0 ? mHandles[0].promote() : 0;
+ // the first valid handle in the list has control over the module
+ for (size_t i = 0; i < mHandles.size(); i++) {
+ EffectHandle *h = mHandles[i];
+ if (h != NULL && !h->destroyed_l()) {
+ return h;
+ }
+ }
+
+ return NULL;
}
-void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle, bool unpinIfLast)
+size_t AudioFlinger::EffectModule::disconnect(EffectHandle *handle, bool unpinIfLast)
{
- ALOGV("disconnect() %p handle %p", this, handle.unsafe_get());
+ ALOGV("disconnect() %p handle %p", this, handle);
// keep a strong reference on this EffectModule to avoid calling the
// destructor before we exit
sp<EffectModule> keep(this);
@@ -8085,6 +8103,7 @@
thread->disconnectEffect(keep, handle, unpinIfLast);
}
}
+ return mHandles.size();
}
void AudioFlinger::EffectModule::updateState() {
@@ -8394,8 +8413,8 @@
if (cmdCode != EFFECT_CMD_GET_PARAM && status == NO_ERROR) {
uint32_t size = (replySize == NULL) ? 0 : *replySize;
for (size_t i = 1; i < mHandles.size(); i++) {
- sp<EffectHandle> h = mHandles[i].promote();
- if (h != 0) {
+ EffectHandle *h = mHandles[i];
+ if (h != NULL && !h->destroyed_l()) {
h->commandExecuted(cmdCode, cmdSize, pCmdData, size, pReplyData);
}
}
@@ -8405,8 +8424,14 @@
status_t AudioFlinger::EffectModule::setEnabled(bool enabled)
{
-
Mutex::Autolock _l(mLock);
+ return setEnabled_l(enabled);
+}
+
+// must be called with EffectModule::mLock held
+status_t AudioFlinger::EffectModule::setEnabled_l(bool enabled)
+{
+
ALOGV("setEnabled %p enabled %d", this, enabled);
if (enabled != isEnabled()) {
@@ -8441,8 +8466,8 @@
return NO_ERROR; // simply ignore as we are being destroyed
}
for (size_t i = 1; i < mHandles.size(); i++) {
- sp<EffectHandle> h = mHandles[i].promote();
- if (h != 0) {
+ EffectHandle *h = mHandles[i];
+ if (h != NULL && !h->destroyed_l()) {
h->setEnabled(enabled);
}
}
@@ -8591,6 +8616,22 @@
return mSuspended;
}
+bool AudioFlinger::EffectModule::purgeHandles()
+{
+ bool enabled = false;
+ Mutex::Autolock _l(mLock);
+ for (size_t i = 0; i < mHandles.size(); i++) {
+ EffectHandle *handle = mHandles[i];
+ if (handle != NULL && !handle->destroyed_l()) {
+ handle->effect().clear();
+ if (handle->hasControl()) {
+ enabled = handle->enabled();
+ }
+ }
+ }
+ return enabled;
+}
+
status_t AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
@@ -8657,8 +8698,8 @@
result.append(buffer);
result.append("\t\t\tPid Priority Ctrl Locked client server\n");
for (size_t i = 0; i < mHandles.size(); ++i) {
- sp<EffectHandle> handle = mHandles[i].promote();
- if (handle != 0) {
+ EffectHandle *handle = mHandles[i];
+ if (handle != NULL && !handle->destroyed_l()) {
handle->dump(buffer, SIZE);
result.append(buffer);
}
@@ -8688,7 +8729,7 @@
int32_t priority)
: BnEffect(),
mEffect(effect), mEffectClient(effectClient), mClient(client), mCblk(NULL),
- mPriority(priority), mHasControl(false), mEnabled(false)
+ mPriority(priority), mHasControl(false), mEnabled(false), mDestroyed(false)
{
ALOGV("constructor %p", this);
@@ -8713,8 +8754,15 @@
AudioFlinger::EffectHandle::~EffectHandle()
{
ALOGV("Destructor %p", this);
+
+ if (mEffect == 0) {
+ mDestroyed = true;
+ return;
+ }
+ mEffect->lock();
+ mDestroyed = true;
+ mEffect->unlock();
disconnect(false);
- ALOGV("Destructor DONE %p", this);
}
status_t AudioFlinger::EffectHandle::enable()
@@ -8785,9 +8833,8 @@
if (mEffect == 0) {
return;
}
- mEffect->disconnect(this, unpinIfLast);
-
- if (mHasControl && mEnabled) {
+ // restore suspended effects if the disconnected handle was enabled and the last one.
+ if ((mEffect->disconnect(this, unpinIfLast) == 0) && mEnabled) {
sp<ThreadBase> thread = mEffect->thread().promote();
if (thread != 0) {
thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
@@ -9370,10 +9417,12 @@
sp<EffectModule> effect = desc->mEffect.promote();
if (effect != 0) {
effect->setSuspended(false);
- sp<EffectHandle> handle = effect->controlHandle();
- if (handle != 0) {
- effect->setEnabled(handle->enabled());
+ effect->lock();
+ EffectHandle *handle = effect->controlHandle_l();
+ if (handle != NULL && !handle->destroyed_l()) {
+ effect->setEnabled_l(handle->enabled());
}
+ effect->unlock();
}
desc->mEffect.clear();
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 384306c..b8bb69e 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -91,7 +91,7 @@
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
- uint32_t channelMask,
+ audio_channel_mask_t channelMask,
int frameCount,
IAudioFlinger::track_flags_t flags,
const sp<IMemory>& sharedBuffer,
@@ -105,7 +105,7 @@
audio_io_handle_t input,
uint32_t sampleRate,
audio_format_t format,
- uint32_t channelMask,
+ audio_channel_mask_t channelMask,
int frameCount,
IAudioFlinger::track_flags_t flags,
int *sessionId,
@@ -142,7 +142,8 @@
virtual void registerClient(const sp<IAudioFlingerClient>& client);
- virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const;
+ virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask) const;
virtual audio_io_handle_t openOutput(audio_module_handle_t module,
audio_devices_t *pDevices,
@@ -253,6 +254,7 @@
int listenerSession,
sync_event_callback_t callBack,
void *cookie);
+
private:
audio_mode_t getMode() const { return mMode; }
@@ -482,13 +484,19 @@
};
virtual status_t initCheck() const = 0;
+
+ // static externally-visible
type_t type() const { return mType; }
+ audio_io_handle_t id() const { return mId;}
+
+ // dynamic externally-visible
uint32_t sampleRate() const { return mSampleRate; }
int channelCount() const { return mChannelCount; }
audio_format_t format() const { return mFormat; }
// Called by AudioFlinger::frameCount(audio_io_handle_t output) and effects,
// and returns the normal mix buffer's frame count. No API for HAL frame count.
size_t frameCount() const { return mNormalFrameCount; }
+
void wakeUp() { mWaitWorkCV.broadcast(); }
// Should be "virtual status_t requestExitAndWait()" and override same
// method in Thread, but Thread::requestExitAndWait() is not yet virtual.
@@ -500,9 +508,11 @@
void sendConfigEvent(int event, int param = 0);
void sendConfigEvent_l(int event, int param = 0);
void processConfigEvents();
- audio_io_handle_t id() const { return mId;}
+
+ // see note at declaration of mStandby and mDevice
bool standby() const { return mStandby; }
- uint32_t device() const { return mDevice; }
+ audio_devices_t device() const { return mDevice; }
+
virtual audio_stream_t* stream() const = 0;
sp<EffectHandle> createEffect_l(
@@ -514,7 +524,7 @@
int *enabled,
status_t *status);
void disconnectEffect(const sp< EffectModule>& effect,
- const wp<EffectHandle>& handle,
+ EffectHandle *handle,
bool unpinIfLast);
// return values for hasAudioSession (bit field)
@@ -543,6 +553,7 @@
// set audio mode to all effect chains
void setMode(audio_mode_t mode);
// get effect module with corresponding ID on specified audio session
+ sp<AudioFlinger::EffectModule> getEffect(int sessionId, int effectId);
sp<AudioFlinger::EffectModule> getEffect_l(int sessionId, int effectId);
// add and effect module. Also creates the effect chain is none exists for
// the effects audio session
@@ -644,11 +655,19 @@
status_t mParamStatus;
Vector<ConfigEvent> mConfigEvents;
- bool mStandby;
+
+ // These fields are written and read by thread itself without lock or barrier,
+ // and read by other threads without lock or barrier via standby() and device().
+ // Because of the absence of a lock or barrier, any other thread that reads
+ // these fields must use the information in isolation, or be prepared to deal
+ // with possibility that it might be inconsistent with other information.
+ bool mStandby; // Whether thread is currently in standby.
+ audio_devices_t mDevice; // output device for PlaybackThread
+ // input + output devices for RecordThread
+
const audio_io_handle_t mId;
Vector< sp<EffectChain> > mEffectChains;
- uint32_t mDevice; // output device for PlaybackThread
- // input + output devices for RecordThread
+
static const int kNameLength = 16; // prctl(PR_SET_NAME) limit
char mName[kNameLength];
sp<IPowerManager> mPowerManager;
@@ -1016,6 +1035,8 @@
virtual status_t setSyncEvent(const sp<SyncEvent>& event);
virtual bool isValidSyncEvent(const sp<SyncEvent>& event);
+ void invalidateTracks(audio_stream_type_t streamType);
+
protected:
int16_t* mMixBuffer;
@@ -1098,7 +1119,6 @@
// FIXME move these declarations into the specific sub-class that needs them
// MIXER only
- bool longStandbyExit;
uint32_t sleepTimeShift;
// same as AudioFlinger::mStandbyTimeInNsecs except for DIRECT which uses a shorter value
@@ -1143,7 +1163,6 @@
// Thread virtuals
- void invalidateTracks(audio_stream_type_t streamType);
virtual bool checkForNewParameters_l();
virtual status_t dumpInternals(int fd, const Vector<String16>& args);
@@ -1165,9 +1184,6 @@
AudioMixer* mAudioMixer; // normal mixer
private:
-#ifdef SOAKER
- Thread* mSoaker;
-#endif
// one-time initialization, no locks required
FastMixer* mFastMixer; // non-NULL if there is also a fast mixer
sp<AudioWatchdog> mAudioWatchdog; // non-0 if there is an audio watchdog thread
@@ -1287,6 +1303,8 @@
PlaybackThread *primaryPlaybackThread_l() const;
uint32_t primaryOutputDevice_l() const;
+ sp<PlaybackThread> getEffectThread_l(int sessionId, int EffectId);
+
// server side of the client's IAudioTrack
class TrackHandle : public android::BnAudioTrack {
public:
@@ -1506,6 +1524,7 @@
return mSessionId;
}
status_t setEnabled(bool enabled);
+ status_t setEnabled_l(bool enabled);
bool isEnabled() const;
bool isProcessEnabled() const;
@@ -1517,9 +1536,9 @@
void setThread(const wp<ThreadBase>& thread) { mThread = thread; }
const wp<ThreadBase>& thread() { return mThread; }
- status_t addHandle(const sp<EffectHandle>& handle);
- void disconnect(const wp<EffectHandle>& handle, bool unpinIfLast);
- size_t removeHandle (const wp<EffectHandle>& handle);
+ status_t addHandle(EffectHandle *handle);
+ size_t disconnect(EffectHandle *handle, bool unpinIfLast);
+ size_t removeHandle(EffectHandle *handle);
effect_descriptor_t& desc() { return mDescriptor; }
wp<EffectChain>& chain() { return mChain; }
@@ -1532,10 +1551,13 @@
void setSuspended(bool suspended);
bool suspended() const;
- sp<EffectHandle> controlHandle();
+ EffectHandle* controlHandle_l();
bool isPinned() const { return mPinned; }
void unPin() { mPinned = false; }
+ bool purgeHandles();
+ void lock() { mLock.lock(); }
+ void unlock() { mLock.unlock(); }
status_t dump(int fd, const Vector<String16>& args);
@@ -1555,14 +1577,14 @@
mutable Mutex mLock; // mutex for process, commands and handles list protection
wp<ThreadBase> mThread; // parent thread
wp<EffectChain> mChain; // parent effect chain
- int mId; // this instance unique ID
- int mSessionId; // audio session ID
+ const int mId; // this instance unique ID
+ const int mSessionId; // audio session ID
effect_descriptor_t mDescriptor;// effect descriptor received from effect engine
effect_config_t mConfig; // input and output audio configuration
effect_handle_t mEffectInterface; // Effect module C API
status_t mStatus; // initialization status
effect_state mState; // current activation state
- Vector< wp<EffectHandle> > mHandles; // list of client handles
+ Vector<EffectHandle *> mHandles; // list of client handles
// First handle in mHandles has highest priority and controls the effect module
uint32_t mMaxDisableWaitCnt; // maximum grace period before forcing an effect off after
// sending disable command.
@@ -1620,6 +1642,8 @@
int priority() const { return mPriority; }
bool hasControl() const { return mHasControl; }
sp<EffectModule> effect() const { return mEffect; }
+ // destroyed_l() must be called with the associated EffectModule mLock held
+ bool destroyed_l() const { return mDestroyed; }
void dump(char* buffer, size_t size);
@@ -1638,6 +1662,8 @@
bool mHasControl; // true if this handle is controlling the effect
bool mEnabled; // cached enable state: needed when the effect is
// restored after being suspended
+ bool mDestroyed; // Set to true by destructor. Access with EffectModule
+ // mLock held
};
// the EffectChain class represents a group of effects associated to one audio session.
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index c32fc6b..02b531c 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -272,7 +272,6 @@
uint32_t samplingRate,
audio_format_t format,
uint32_t channels,
- audio_in_acoustics_t acoustics,
int audioSession)
{
if (mpAudioPolicy == NULL) {
@@ -283,8 +282,9 @@
return 0;
}
Mutex::Autolock _l(mLock);
+ // the audio_in_acoustics_t parameter is ignored by get_input()
audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
- format, channels, acoustics);
+ format, channels, (audio_in_acoustics_t) 0);
if (input == 0) {
return input;
@@ -1424,7 +1424,7 @@
return af->restoreOutput(output);
}
-// deprecated: replaced by aps_open_input_on_module()
+// deprecated: replaced by aps_open_input_on_module(), and acoustics parameter is ignored
static audio_io_handle_t aps_open_input(void *service,
audio_devices_t *pDevices,
uint32_t *pSamplingRate,
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index fbca000..b4924fc 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -78,8 +78,6 @@
uint32_t samplingRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
- audio_in_acoustics_t acoustics =
- (audio_in_acoustics_t)0 /*AUDIO_IN_ACOUSTICS_NONE*/,
int audioSession = 0);
virtual status_t startInput(audio_io_handle_t input);
virtual status_t stopInput(audio_io_handle_t input);
diff --git a/services/audioflinger/Soaker.h b/services/audioflinger/Soaker.h
deleted file mode 100644
index 43d9d2f..0000000
--- a/services/audioflinger/Soaker.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_AUDIO_SOAKER_H
-#define _ANDROID_AUDIO_SOAKER_H
-
-#include <utils/Thread.h>
-
-namespace android {
-
-class Soaker : public Thread {
-public:
- Soaker() : Thread() { }
- virtual ~Soaker() { }
-protected:
- virtual bool threadLoop() {
- int j = 0;
- for (;;) {
- for (int i = 0; i < 10000; ++i) {
- j += i * i;
- }
- if (exitPending()) {
- return false;
- }
- }
- return j < 555555;
- }
-};
-
-} // namespace android
-
-#endif // _ANDROID_AUDIO_SOAKER_H
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 9f713fa..8cccf49 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -22,6 +22,7 @@
libcamera_client \
libgui \
libhardware \
+ libsync \
libcamera_metadata
LOCAL_C_INCLUDES += \
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index 5a37c8d..8d07eee 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -758,7 +758,7 @@
ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
uint32_t bufferIdx = 0;
for (; bufferIdx < mTotalBuffers; bufferIdx++) {
- res = mConsumerInterface->dequeueBuffer(mConsumerInterface.get(),
+ res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
&anwBuffers[bufferIdx]);
if (res != OK) {
ALOGE("%s: Unable to dequeue buffer %d for initial registration for"
@@ -766,15 +766,6 @@
goto cleanUpBuffers;
}
- res = mConsumerInterface->lockBuffer(mConsumerInterface.get(),
- anwBuffers[bufferIdx]);
- if (res != OK) {
- ALOGE("%s: Unable to lock buffer %d for initial registration for"
- "stream %d", __FUNCTION__, bufferIdx, mId);
- bufferIdx++;
- goto cleanUpBuffers;
- }
-
buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
}
@@ -792,7 +783,7 @@
cleanUpBuffers:
for (uint32_t i = 0; i < bufferIdx; i++) {
res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
- anwBuffers[i]);
+ anwBuffers[i], -1);
if (res != OK) {
ALOGE("%s: Unable to cancel buffer %d after registration",
__FUNCTION__, i);
@@ -878,9 +869,7 @@
ANativeWindow *a = toANW(w);
ANativeWindowBuffer* anb;
- res = a->dequeueBuffer(a, &anb);
- if (res != OK) return res;
- res = a->lockBuffer(a, anb);
+ res = native_window_dequeue_buffer_and_wait(a, &anb);
if (res != OK) return res;
*buffer = &(anb->handle);
@@ -911,7 +900,7 @@
return err;
}
err = a->queueBuffer(a,
- container_of(buffer, ANativeWindowBuffer, handle));
+ container_of(buffer, ANativeWindowBuffer, handle), -1);
if (err != OK) {
ALOGE("%s: Error queueing buffer to native window: %s (%d)",
__FUNCTION__, strerror(-err), err);
@@ -933,7 +922,7 @@
stream->mActiveBuffers--;
ANativeWindow *a = toANW(w);
return a->cancelBuffer(a,
- container_of(buffer, ANativeWindowBuffer, handle));
+ container_of(buffer, ANativeWindowBuffer, handle), -1);
}
int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
index 87a0802..05ac9fa 100644
--- a/services/camera/libcameraservice/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -569,7 +569,7 @@
int rc;
ANativeWindow *a = anw(w);
ANativeWindowBuffer* anb;
- rc = a->dequeueBuffer(a, &anb);
+ rc = native_window_dequeue_buffer_and_wait(a, &anb);
if (!rc) {
*buffer = &anb->handle;
*stride = anb->stride;
@@ -587,8 +587,7 @@
buffer_handle_t* buffer)
{
ANativeWindow *a = anw(w);
- return a->lockBuffer(a,
- container_of(buffer, ANativeWindowBuffer, handle));
+ return 0;
}
static int __enqueue_buffer(struct preview_stream_ops* w,
@@ -596,7 +595,7 @@
{
ANativeWindow *a = anw(w);
return a->queueBuffer(a,
- container_of(buffer, ANativeWindowBuffer, handle));
+ container_of(buffer, ANativeWindowBuffer, handle), -1);
}
static int __cancel_buffer(struct preview_stream_ops* w,
@@ -604,7 +603,7 @@
{
ANativeWindow *a = anw(w);
return a->cancelBuffer(a,
- container_of(buffer, ANativeWindowBuffer, handle));
+ container_of(buffer, ANativeWindowBuffer, handle), -1);
}
static int __set_buffer_count(struct preview_stream_ops* w, int count)