Merge "AudioRecord locking"
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index cc18a1d..163205e 100755
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -42,6 +42,7 @@
namespace android {
+static const int64_t kMinStreamableFileSizeInBytes = 5 * 1024 * 1024;
static const int64_t kMax32BitFileSize = 0x007fffffffLL;
static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
static const uint8_t kNalUnitTypePicParamSet = 0x08;
@@ -487,8 +488,16 @@
CHECK_GT(mTimeScale, 0);
ALOGV("movie time scale: %d", mTimeScale);
- mStreamableFile = true;
- mWriteMoovBoxToMemory = false;
+ /*
+ * When the requested file size limit is small, the priority
+ * is to meet the file size limit requirement, rather than
+ * to make the file streamable.
+ */
+ mStreamableFile =
+ (mMaxFileSizeLimitBytes != 0 &&
+ mMaxFileSizeLimitBytes >= kMinStreamableFileSizeInBytes);
+
+ mWriteMoovBoxToMemory = mStreamableFile;
mMoovBoxBuffer = NULL;
mMoovBoxBufferOffset = 0;
@@ -504,11 +513,16 @@
mEstimatedMoovBoxSize = estimateMoovBoxSize(bitRate);
}
CHECK_GE(mEstimatedMoovBoxSize, 8);
- lseek64(mFd, mFreeBoxOffset, SEEK_SET);
- writeInt32(mEstimatedMoovBoxSize);
- write("free", 4);
+ if (mStreamableFile) {
+ // Reserve a 'free' box only for streamable file
+ lseek64(mFd, mFreeBoxOffset, SEEK_SET);
+ writeInt32(mEstimatedMoovBoxSize);
+ write("free", 4);
+ mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize;
+ } else {
+ mMdatOffset = mOffset;
+ }
- mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize;
mOffset = mMdatOffset;
lseek64(mFd, mMdatOffset, SEEK_SET);
if (mUse32BitOffset) {
@@ -689,7 +703,7 @@
lseek64(mFd, mOffset, SEEK_SET);
const off64_t moovOffset = mOffset;
- mWriteMoovBoxToMemory = true;
+ mWriteMoovBoxToMemory = mStreamableFile;
mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
mMoovBoxBufferOffset = 0;
CHECK(mMoovBoxBuffer != NULL);
@@ -1062,6 +1076,10 @@
nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
}
+ if (!mStreamableFile) {
+ // Add 1024 bytes as error tolerance
+ return nTotalBytesEstimate + 1024 >= mMaxFileSizeLimitBytes;
+ }
// Be conservative in the estimate: do not exceed 95% of
// the target file limit. For small target file size limit, though,
// this will not help.
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f033080..b2aa388 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -273,7 +273,7 @@
};
#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))
-audio_hw_device_t* AudioFlinger::findSuitableHwDev_l(audio_module_handle_t module, uint32_t devices)
+audio_hw_device_t* AudioFlinger::findSuitableHwDev_l(audio_module_handle_t module, audio_devices_t devices)
{
// if module is 0, the request comes from an old policy manager and we should load
// well known modules
@@ -873,8 +873,7 @@
sp<RecordThread> thread = mRecordThreads.valueAt(i);
RecordThread::RecordTrack *track = thread->track();
if (track != NULL) {
- audio_devices_t device = (audio_devices_t)(
- thread->device() & AUDIO_DEVICE_IN_ALL);
+ audio_devices_t device = thread->device() & AUDIO_DEVICE_IN_ALL;
bool suspend = audio_is_bluetooth_sco_device(device) && btNrecIsOff;
thread->setEffectSuspended(FX_IID_AEC,
suspend,
@@ -1116,7 +1115,7 @@
// ----------------------------------------------------------------------------
AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
- uint32_t device, type_t type)
+ audio_devices_t device, type_t type)
: Thread(false),
mType(type),
mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mNormalFrameCount(0),
@@ -1124,7 +1123,7 @@
mChannelCount(0),
mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),
mParamStatus(NO_ERROR),
- mStandby(false), mDevice((audio_devices_t) device), mId(id),
+ mStandby(false), mDevice(device), mId(id),
mDeathRecipient(new PMDeathRecipient(this))
{
}
@@ -1500,7 +1499,7 @@
AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
AudioStreamOut* output,
audio_io_handle_t id,
- uint32_t device,
+ audio_devices_t device,
type_t type)
: ThreadBase(audioFlinger, id, device, type),
mMixBuffer(NULL), mSuspended(0), mBytesWritten(0),
@@ -2181,7 +2180,7 @@
// ----------------------------------------------------------------------------
AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
- audio_io_handle_t id, uint32_t device, type_t type)
+ audio_io_handle_t id, audio_devices_t device, type_t type)
: PlaybackThread(audioFlinger, output, id, device, type),
// mAudioMixer below
// mFastMixer below
@@ -2190,7 +2189,7 @@
// mPipeSink below
// mNormalSink below
{
- ALOGV("MixerThread() id=%d device=%d type=%d", id, device, type);
+ ALOGV("MixerThread() id=%d device=%#x type=%d", id, device, type);
ALOGV("mSampleRate=%d, mChannelMask=%#x, mChannelCount=%d, mFormat=%d, mFrameSize=%d, "
"mFrameCount=%d, mNormalFrameCount=%d",
mSampleRate, mChannelMask, mChannelCount, mFormat, mFrameSize, mFrameCount,
@@ -3420,14 +3419,14 @@
#ifdef ADD_BATTERY_DATA
// when changing the audio output device, call addBatteryData to notify
// the change
- if ((int)mDevice != value) {
+ if (mDevice != value) {
uint32_t params = 0;
// check whether speaker is on
if (value & AUDIO_DEVICE_OUT_SPEAKER) {
params |= IMediaPlayerService::kBatteryDataSpeakerOn;
}
- int deviceWithoutSpeaker
+ audio_devices_t deviceWithoutSpeaker
= AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_SPEAKER;
// check if any other device (except speaker) is on
if (value & deviceWithoutSpeaker ) {
@@ -3442,7 +3441,7 @@
// forward device change to effects that have requested to be
// aware of attached audio device.
- mDevice = (audio_devices_t) value;
+ mDevice = value;
for (size_t i = 0; i < mEffectChains.size(); i++) {
mEffectChains[i]->setDevice_l(mDevice);
}
@@ -3611,7 +3610,7 @@
// ----------------------------------------------------------------------------
AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
- AudioStreamOut* output, audio_io_handle_t id, uint32_t device)
+ AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device)
: PlaybackThread(audioFlinger, output, id, device, DIRECT)
// mLeftVolFloat, mRightVolFloat
{
@@ -5900,7 +5899,7 @@
uint32_t sampleRate,
audio_channel_mask_t channelMask,
audio_io_handle_t id,
- uint32_t device) :
+ audio_devices_t device) :
ThreadBase(audioFlinger, id, device, RECORD),
mInput(input), mTrack(NULL), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL),
// mRsmpInIndex and mInputBytes set by readInputParameters()
@@ -6179,8 +6178,8 @@
mTrack = track.get();
// disable AEC and NS if the device is a BT SCO headset supporting those pre processings
- bool suspend = audio_is_bluetooth_sco_device(
- (audio_devices_t)(mDevice & AUDIO_DEVICE_IN_ALL)) && mAudioFlinger->btNrecIsOff();
+ bool suspend = audio_is_bluetooth_sco_device(mDevice & AUDIO_DEVICE_IN_ALL) &&
+ mAudioFlinger->btNrecIsOff();
setEffectSuspended_l(FX_IID_AEC, suspend, sessionId);
setEffectSuspended_l(FX_IID_NS, suspend, sessionId);
}
@@ -6469,12 +6468,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;
+ audio_devices_t newDevice = mDevice;
if (value & AUDIO_DEVICE_OUT_ALL) {
- newDevice &= (uint32_t)~(value & AUDIO_DEVICE_OUT_ALL);
+ newDevice &= ~(value & AUDIO_DEVICE_OUT_ALL);
status = BAD_VALUE;
} else {
- newDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
+ newDevice &= ~(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(
@@ -6484,7 +6483,7 @@
}
}
newDevice |= value;
- mDevice = (audio_devices_t) newDevice; // since mDevice is read by other threads, only write to it once
+ mDevice = 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());
@@ -6725,7 +6724,7 @@
ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %d, Channels %x, flags %x",
module,
- (pDevices != NULL) ? (int)*pDevices : 0,
+ (pDevices != NULL) ? *pDevices : 0,
config.sample_rate,
config.format,
config.channel_mask,
@@ -6985,7 +6984,7 @@
// Start record thread
// RecorThread require both input and output device indication to forward to audio
// pre processing modules
- uint32_t device = (*pDevices) | primaryOutputDevice_l();
+ audio_devices_t device = (*pDevices) | primaryOutputDevice_l();
thread = new RecordThread(this,
input,
reqSamplingRate,
@@ -7195,7 +7194,7 @@
return NULL;
}
-uint32_t AudioFlinger::primaryOutputDevice_l() const
+audio_devices_t AudioFlinger::primaryOutputDevice_l() const
{
PlaybackThread *thread = primaryPlaybackThread_l();
@@ -8534,14 +8533,14 @@
return status;
}
-status_t AudioFlinger::EffectModule::setDevice(uint32_t device)
+status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
{
Mutex::Autolock _l(mLock);
status_t status = NO_ERROR;
if (device && (mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
// audio pre processing modules on RecordThread can receive both output and
// input device indication in the same call
- uint32_t dev = device & AUDIO_DEVICE_OUT_ALL;
+ audio_devices_t dev = device & AUDIO_DEVICE_OUT_ALL;
if (dev) {
status_t cmdStatus;
uint32_t size = sizeof(status_t);
@@ -9258,7 +9257,7 @@
}
// setDevice_l() must be called with PlaybackThread::mLock held
-void AudioFlinger::EffectChain::setDevice_l(uint32_t device)
+void AudioFlinger::EffectChain::setDevice_l(audio_devices_t device)
{
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index fa1ad93..c6f08cd 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -270,7 +270,7 @@
// RefBase
virtual void onFirstRef();
- audio_hw_device_t* findSuitableHwDev_l(audio_module_handle_t module, uint32_t devices);
+ audio_hw_device_t* findSuitableHwDev_l(audio_module_handle_t module, audio_devices_t devices);
void purgeStaleEffects_l();
// standby delay for MIXER and DUPLICATING playback threads is read from property
@@ -352,7 +352,7 @@
RECORD // Thread class is RecordThread
};
- ThreadBase (const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, uint32_t device, type_t type);
+ ThreadBase (const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, audio_devices_t device, type_t type);
virtual ~ThreadBase();
status_t dumpBase(int fd, const Vector<String16>& args);
@@ -963,7 +963,7 @@
}; // end of OutputTrack
PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
- audio_io_handle_t id, uint32_t device, type_t type);
+ audio_io_handle_t id, audio_devices_t device, type_t type);
virtual ~PlaybackThread();
status_t dump(int fd, const Vector<String16>& args);
@@ -1185,7 +1185,7 @@
MixerThread (const sp<AudioFlinger>& audioFlinger,
AudioStreamOut* output,
audio_io_handle_t id,
- uint32_t device,
+ audio_devices_t device,
type_t type = MIXER);
virtual ~MixerThread();
@@ -1240,7 +1240,7 @@
public:
DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
- audio_io_handle_t id, uint32_t device);
+ audio_io_handle_t id, audio_devices_t device);
virtual ~DirectOutputThread();
// Thread virtuals
@@ -1329,7 +1329,7 @@
bool reRegister);
// return thread associated with primary hardware device, or NULL
PlaybackThread *primaryPlaybackThread_l() const;
- uint32_t primaryOutputDevice_l() const;
+ audio_devices_t primaryOutputDevice_l() const;
sp<PlaybackThread> getEffectThread_l(int sessionId, int EffectId);
@@ -1407,7 +1407,7 @@
uint32_t sampleRate,
audio_channel_mask_t channelMask,
audio_io_handle_t id,
- uint32_t device);
+ audio_devices_t device);
virtual ~RecordThread();
// Thread
@@ -1575,7 +1575,7 @@
effect_descriptor_t& desc() { return mDescriptor; }
wp<EffectChain>& chain() { return mChain; }
- status_t setDevice(uint32_t device);
+ status_t setDevice(audio_devices_t device);
status_t setVolume(uint32_t *left, uint32_t *right, bool controller);
status_t setMode(audio_mode_t mode);
status_t start();
@@ -1738,7 +1738,7 @@
sp<EffectModule> getEffectFromId_l(int id);
sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type);
bool setVolume_l(uint32_t *left, uint32_t *right);
- void setDevice_l(uint32_t device);
+ void setDevice_l(audio_devices_t device);
void setMode_l(audio_mode_t mode);
void setInBuffer(int16_t *buffer, bool ownsBuffer = false) {