1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <inttypes.h>
18 #include <stdlib.h>
19
20 //#define LOG_NDEBUG 0
21 #define LOG_TAG "AudioSource"
22 #include <utils/Log.h>
23
24 #include <binder/IPCThreadState.h>
25 #include <media/AidlConversion.h>
26 #include <media/AudioRecord.h>
27 #include <media/stagefright/AudioSource.h>
28 #include <media/stagefright/MediaBuffer.h>
29 #include <media/stagefright/MediaDefs.h>
30 #include <media/stagefright/MetaData.h>
31 #include <media/stagefright/foundation/ADebug.h>
32 #include <media/stagefright/foundation/ALooper.h>
33 #include <cutils/properties.h>
34
35 namespace android {
36
37 using content::AttributionSourceState;
38
39
onOverrun()40 void AudioSource::onOverrun() {
41 ALOGW("AudioRecord reported overrun!");
42 }
43
AudioSource(const audio_attributes_t * attr,const AttributionSourceState & attributionSource,uint32_t sampleRate,uint32_t channelCount,uint32_t outSampleRate,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float selectedMicFieldDimension)44 AudioSource::AudioSource(
45 const audio_attributes_t *attr, const AttributionSourceState& attributionSource,
46 uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
47 audio_port_handle_t selectedDeviceId,
48 audio_microphone_direction_t selectedMicDirection,
49 float selectedMicFieldDimension)
50 {
51 set(attr, attributionSource, sampleRate, channelCount, outSampleRate, selectedDeviceId,
52 selectedMicDirection, selectedMicFieldDimension);
53 }
54
AudioSource(const audio_attributes_t * attr,const String16 & opPackageName,uint32_t sampleRate,uint32_t channelCount,uint32_t outSampleRate,uid_t uid,pid_t pid,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float selectedMicFieldDimension)55 AudioSource::AudioSource(
56 const audio_attributes_t *attr, const String16 &opPackageName,
57 uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
58 uid_t uid, pid_t pid, audio_port_handle_t selectedDeviceId,
59 audio_microphone_direction_t selectedMicDirection,
60 float selectedMicFieldDimension)
61 {
62 // TODO b/182392769: use attribution source util
63 AttributionSourceState attributionSource;
64 attributionSource.packageName = VALUE_OR_FATAL(legacy2aidl_String16_string(opPackageName));
65 attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(uid));
66 attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(pid));
67 attributionSource.token = sp<BBinder>::make();
68 set(attr, attributionSource, sampleRate, channelCount, outSampleRate, selectedDeviceId,
69 selectedMicDirection, selectedMicFieldDimension);
70 }
71
set(const audio_attributes_t * attr,const AttributionSourceState & attributionSource,uint32_t sampleRate,uint32_t channelCount,uint32_t outSampleRate,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float selectedMicFieldDimension)72 void AudioSource::set(
73 const audio_attributes_t *attr, const AttributionSourceState& attributionSource,
74 uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
75 audio_port_handle_t selectedDeviceId,
76 audio_microphone_direction_t selectedMicDirection,
77 float selectedMicFieldDimension)
78 {
79 mStarted = false;
80 mSampleRate = sampleRate;
81 mOutSampleRate = outSampleRate > 0 ? outSampleRate : sampleRate;
82 mTrackMaxAmplitude = false;
83 mStartTimeUs = 0;
84 mStopSystemTimeUs = -1;
85 mLastFrameTimestampUs = 0;
86 mMaxAmplitude = 0;
87 mPrevSampleTimeUs = 0;
88 mInitialReadTimeUs = 0;
89 mNumFramesReceived = 0;
90 mNumFramesSkipped = 0;
91 mNumFramesLost = 0;
92 mNumClientOwnedBuffers = 0;
93 mNoMoreFramesToRead = false;
94 ALOGV("sampleRate: %u, outSampleRate: %u, channelCount: %u",
95 sampleRate, outSampleRate, channelCount);
96 CHECK(channelCount == 1 || channelCount == 2);
97 CHECK(sampleRate > 0);
98
99 size_t minFrameCount;
100 status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
101 sampleRate,
102 AUDIO_FORMAT_PCM_16_BIT,
103 audio_channel_in_mask_from_count(channelCount));
104 if (status == OK) {
105 // make sure that the AudioRecord callback never returns more than the maximum
106 // buffer size
107 uint32_t frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount;
108
109 // make sure that the AudioRecord total buffer size is large enough
110 size_t bufCount = 2;
111 while ((bufCount * frameCount) < minFrameCount) {
112 bufCount++;
113 }
114
115 mRecord = new AudioRecord(
116 AUDIO_SOURCE_DEFAULT, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
117 audio_channel_in_mask_from_count(channelCount),
118 attributionSource,
119 (size_t) (bufCount * frameCount),
120 wp<AudioRecord::IAudioRecordCallback>{this},
121 frameCount /*notificationFrames*/,
122 AUDIO_SESSION_ALLOCATE,
123 AudioRecord::TRANSFER_DEFAULT,
124 AUDIO_INPUT_FLAG_NONE,
125 attr,
126 selectedDeviceId,
127 selectedMicDirection,
128 selectedMicFieldDimension);
129 // Set caller name so it can be logged in destructor.
130 // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_MEDIA
131 mRecord->setCallerName("media");
132 mInitCheck = mRecord->initCheck();
133 if (mInitCheck != OK) {
134 mRecord.clear();
135 }
136 } else {
137 mInitCheck = status;
138 }
139 }
140
~AudioSource()141 AudioSource::~AudioSource() {
142 if (mStarted) {
143 reset();
144 }
145 }
146
initCheck() const147 status_t AudioSource::initCheck() const {
148 return mInitCheck;
149 }
150
start(MetaData * params)151 status_t AudioSource::start(MetaData *params) {
152 Mutex::Autolock autoLock(mLock);
153 if (mStarted) {
154 return UNKNOWN_ERROR;
155 }
156
157 if (mInitCheck != OK) {
158 return NO_INIT;
159 }
160
161 mTrackMaxAmplitude = false;
162 mMaxAmplitude = 0;
163 mInitialReadTimeUs = 0;
164 mStartTimeUs = 0;
165 int64_t startTimeUs;
166 if (params && params->findInt64(kKeyTime, &startTimeUs)) {
167 mStartTimeUs = startTimeUs;
168 }
169 status_t err = mRecord->start();
170 if (err == OK) {
171 mStarted = true;
172 } else {
173 mRecord.clear();
174 }
175
176
177 return err;
178 }
179
releaseQueuedFrames_l()180 void AudioSource::releaseQueuedFrames_l() {
181 ALOGV("releaseQueuedFrames_l");
182 List<MediaBuffer *>::iterator it;
183 while (!mBuffersReceived.empty()) {
184 it = mBuffersReceived.begin();
185 (*it)->release();
186 mBuffersReceived.erase(it);
187 }
188 }
189
waitOutstandingEncodingFrames_l()190 void AudioSource::waitOutstandingEncodingFrames_l() {
191 ALOGV("waitOutstandingEncodingFrames_l: %" PRId64, mNumClientOwnedBuffers);
192 while (mNumClientOwnedBuffers > 0) {
193 mFrameEncodingCompletionCondition.wait(mLock);
194 }
195 }
196
reset()197 status_t AudioSource::reset() {
198 Mutex::Autolock autoLock(mLock);
199 if (!mStarted) {
200 return UNKNOWN_ERROR;
201 }
202
203 if (mInitCheck != OK) {
204 return NO_INIT;
205 }
206
207 mStarted = false;
208 mStopSystemTimeUs = -1;
209 mNoMoreFramesToRead = false;
210 mFrameAvailableCondition.signal();
211
212 mRecord->stop();
213 waitOutstandingEncodingFrames_l();
214 releaseQueuedFrames_l();
215
216 return OK;
217 }
218
getFormat()219 sp<MetaData> AudioSource::getFormat() {
220 Mutex::Autolock autoLock(mLock);
221 if (mInitCheck != OK) {
222 return 0;
223 }
224
225 sp<MetaData> meta = new MetaData;
226 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
227 meta->setInt32(kKeySampleRate, mSampleRate);
228 meta->setInt32(kKeyChannelCount, mRecord->channelCount());
229 meta->setInt32(kKeyMaxInputSize, kMaxBufferSize);
230 meta->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
231
232 return meta;
233 }
234
rampVolume(int32_t startFrame,int32_t rampDurationFrames,uint8_t * data,size_t bytes)235 void AudioSource::rampVolume(
236 int32_t startFrame, int32_t rampDurationFrames,
237 uint8_t *data, size_t bytes) {
238
239 const int32_t kShift = 14;
240 int32_t fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
241 const int32_t nChannels = mRecord->channelCount();
242 int32_t stopFrame = startFrame + bytes / sizeof(int16_t);
243 int16_t *frame = (int16_t *) data;
244 if (stopFrame > rampDurationFrames) {
245 stopFrame = rampDurationFrames;
246 }
247
248 while (startFrame < stopFrame) {
249 if (nChannels == 1) { // mono
250 frame[0] = (frame[0] * fixedMultiplier) >> kShift;
251 ++frame;
252 ++startFrame;
253 } else { // stereo
254 frame[0] = (frame[0] * fixedMultiplier) >> kShift;
255 frame[1] = (frame[1] * fixedMultiplier) >> kShift;
256 frame += 2;
257 startFrame += 2;
258 }
259
260 // Update the multiplier every 4 frames
261 if ((startFrame & 3) == 0) {
262 fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
263 }
264 }
265 }
266
read(MediaBufferBase ** out,const ReadOptions *)267 status_t AudioSource::read(
268 MediaBufferBase **out, const ReadOptions * /* options */) {
269 Mutex::Autolock autoLock(mLock);
270 *out = NULL;
271
272 if (mInitCheck != OK) {
273 return NO_INIT;
274 }
275
276 while (mStarted && mBuffersReceived.empty()) {
277 mFrameAvailableCondition.wait(mLock);
278 if (mNoMoreFramesToRead) {
279 return OK;
280 }
281 }
282 if (!mStarted) {
283 return OK;
284 }
285 MediaBuffer *buffer = *mBuffersReceived.begin();
286 mBuffersReceived.erase(mBuffersReceived.begin());
287 ++mNumClientOwnedBuffers;
288 buffer->setObserver(this);
289 buffer->add_ref();
290
291 // Mute/suppress the recording sound
292 int64_t timeUs;
293 CHECK(buffer->meta_data().findInt64(kKeyTime, &timeUs));
294 int64_t elapsedTimeUs = timeUs - mStartTimeUs;
295 if (elapsedTimeUs < kAutoRampStartUs) {
296 memset((uint8_t *) buffer->data(), 0, buffer->range_length());
297 } else if (elapsedTimeUs < kAutoRampStartUs + kAutoRampDurationUs) {
298 int32_t autoRampDurationFrames =
299 ((int64_t)kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL; //Need type casting
300
301 int32_t autoRampStartFrames =
302 ((int64_t)kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL; //Need type casting
303
304 int32_t nFrames = mNumFramesReceived - autoRampStartFrames;
305 rampVolume(nFrames, autoRampDurationFrames,
306 (uint8_t *) buffer->data(), buffer->range_length());
307 }
308
309 // Track the max recording signal amplitude.
310 if (mTrackMaxAmplitude) {
311 trackMaxAmplitude(
312 (int16_t *) buffer->data(), buffer->range_length() >> 1);
313 }
314
315 if (mSampleRate != mOutSampleRate) {
316 timeUs *= (int64_t)mSampleRate / (int64_t)mOutSampleRate;
317 buffer->meta_data().setInt64(kKeyTime, timeUs);
318 }
319
320 *out = buffer;
321 return OK;
322 }
323
setStopTimeUs(int64_t stopTimeUs)324 status_t AudioSource::setStopTimeUs(int64_t stopTimeUs) {
325 Mutex::Autolock autoLock(mLock);
326 ALOGV("Set stoptime: %lld us", (long long)stopTimeUs);
327
328 if (stopTimeUs < -1) {
329 ALOGE("Invalid stop time %lld us", (long long)stopTimeUs);
330 return BAD_VALUE;
331 } else if (stopTimeUs == -1) {
332 ALOGI("reset stopTime to be -1");
333 }
334
335 mStopSystemTimeUs = stopTimeUs;
336 return OK;
337 }
338
signalBufferReturned(MediaBufferBase * buffer)339 void AudioSource::signalBufferReturned(MediaBufferBase *buffer) {
340 ALOGV("signalBufferReturned: %p", buffer->data());
341 Mutex::Autolock autoLock(mLock);
342 --mNumClientOwnedBuffers;
343 buffer->setObserver(0);
344 buffer->release();
345 mFrameEncodingCompletionCondition.signal();
346 return;
347 }
348
onMoreData(const AudioRecord::Buffer & audioBuffer)349 size_t AudioSource::onMoreData(const AudioRecord::Buffer& audioBuffer) {
350 int64_t timeUs, position, timeNs;
351 ExtendedTimestamp ts;
352 ExtendedTimestamp::Location location;
353 const int32_t usPerSec = 1000000;
354
355 if (mRecord->getTimestamp(&ts) == OK &&
356 ts.getBestTimestamp(&position, &timeNs, ExtendedTimestamp::TIMEBASE_MONOTONIC,
357 &location) == OK) {
358 // Use audio timestamp.
359 timeUs = timeNs / 1000 -
360 (position - mNumFramesSkipped -
361 mNumFramesReceived + mNumFramesLost) * usPerSec / mSampleRate;
362 } else {
363 // This should not happen in normal case.
364 ALOGW("Failed to get audio timestamp, fallback to use systemclock");
365 timeUs = systemTime() / 1000LL;
366 // Estimate the real sampling time of the 1st sample in this buffer
367 // from AudioRecord's latency. (Apply this adjustment first so that
368 // the start time logic is not affected.)
369 timeUs -= mRecord->latency() * 1000LL;
370 }
371
372 ALOGV("dataCallbackTimestamp: %" PRId64 " us", timeUs);
373 Mutex::Autolock autoLock(mLock);
374
375 if (!mStarted) {
376 ALOGW("Spurious callback from AudioRecord. Drop the audio data.");
377 return audioBuffer.size();
378 }
379
380
381 // Drop retrieved and previously lost audio data.
382 if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
383 (void) mRecord->getInputFramesLost();
384 int64_t receievedFrames = audioBuffer.size() / mRecord->frameSize();
385 ALOGV("Drop audio data(%" PRId64 " frames) at %" PRId64 "/%" PRId64 " us",
386 receievedFrames, timeUs, mStartTimeUs);
387 mNumFramesSkipped += receievedFrames;
388 return audioBuffer.size();
389 }
390
391 if (mStopSystemTimeUs != -1 && timeUs >= mStopSystemTimeUs) {
392 ALOGV("Drop Audio frame at %lld stop time: %lld us",
393 (long long)timeUs, (long long)mStopSystemTimeUs);
394 mNoMoreFramesToRead = true;
395 mFrameAvailableCondition.signal();
396 return audioBuffer.size();
397 }
398
399 if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
400 mInitialReadTimeUs = timeUs;
401 // Initial delay
402 if (mStartTimeUs > 0) {
403 mStartTimeUs = timeUs - mStartTimeUs;
404 }
405 mPrevSampleTimeUs = mStartTimeUs;
406 }
407 mLastFrameTimestampUs = timeUs;
408
409 uint64_t numLostBytes = 0; // AudioRecord::getInputFramesLost() returns uint32_t
410 if (mNumFramesReceived > 0) { // Ignore earlier frame lost
411 // getInputFramesLost() returns the number of lost frames.
412 // Convert number of frames lost to number of bytes lost.
413 numLostBytes = (uint64_t)mRecord->getInputFramesLost() * mRecord->frameSize();
414 }
415
416 CHECK_EQ(numLostBytes & 1, 0u);
417 CHECK_EQ(audioBuffer.size() & 1, 0u);
418 if (numLostBytes > 0) {
419 // Loss of audio frames should happen rarely; thus the LOGW should
420 // not cause a logging spam
421 ALOGW("Lost audio record data: %" PRIu64 " bytes", numLostBytes);
422 }
423
424 while (numLostBytes > 0) {
425 uint64_t bufferSize = numLostBytes;
426 if (numLostBytes > kMaxBufferSize) {
427 numLostBytes -= kMaxBufferSize;
428 bufferSize = kMaxBufferSize;
429 } else {
430 numLostBytes = 0;
431 }
432 MediaBuffer *lostAudioBuffer = new MediaBuffer(bufferSize);
433 memset(lostAudioBuffer->data(), 0, bufferSize);
434 lostAudioBuffer->set_range(0, bufferSize);
435 mNumFramesLost += bufferSize / mRecord->frameSize();
436 queueInputBuffer_l(lostAudioBuffer, timeUs);
437 }
438
439 if (audioBuffer.size() == 0) {
440 ALOGW("Nothing is available from AudioRecord callback buffer");
441 return audioBuffer.size();
442 }
443
444 MediaBuffer *buffer = new MediaBuffer(audioBuffer.size());
445 memcpy((uint8_t *) buffer->data(),
446 audioBuffer.data(), audioBuffer.size());
447 buffer->set_range(0, audioBuffer.size());
448 queueInputBuffer_l(buffer, timeUs);
449 return audioBuffer.size();
450 }
451
queueInputBuffer_l(MediaBuffer * buffer,int64_t timeUs)452 void AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) {
453 const size_t bufferSize = buffer->range_length();
454 const size_t frameSize = mRecord->frameSize();
455 if (mNumFramesReceived == 0) {
456 buffer->meta_data().setInt64(kKeyAnchorTime, mStartTimeUs);
457 }
458 mNumFramesReceived += bufferSize / frameSize;
459 const int64_t timestampUs =
460 mStartTimeUs +
461 ((1000000LL * mNumFramesReceived) +
462 (mSampleRate >> 1)) / mSampleRate;
463 buffer->meta_data().setInt64(kKeyTime, mPrevSampleTimeUs);
464 buffer->meta_data().setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
465 mPrevSampleTimeUs = timestampUs;
466 mBuffersReceived.push_back(buffer);
467 mFrameAvailableCondition.signal();
468 }
469
trackMaxAmplitude(int16_t * data,int nSamples)470 void AudioSource::trackMaxAmplitude(int16_t *data, int nSamples) {
471 for (int i = nSamples; i > 0; --i) {
472 int16_t value = *data++;
473 if (value < 0) {
474 value = -value;
475 }
476 if (mMaxAmplitude < value) {
477 mMaxAmplitude = value;
478 }
479 }
480 }
481
getMaxAmplitude()482 int16_t AudioSource::getMaxAmplitude() {
483 // First call activates the tracking.
484 if (!mTrackMaxAmplitude) {
485 mTrackMaxAmplitude = true;
486 }
487 int16_t value = mMaxAmplitude;
488 mMaxAmplitude = 0;
489 ALOGV("max amplitude since last call: %d", value);
490 return value;
491 }
492
setInputDevice(audio_port_handle_t deviceId)493 status_t AudioSource::setInputDevice(audio_port_handle_t deviceId) {
494 if (mRecord != 0) {
495 return mRecord->setInputDevice(deviceId);
496 }
497 return NO_INIT;
498 }
499
getRoutedDeviceId(audio_port_handle_t * deviceId)500 status_t AudioSource::getRoutedDeviceId(audio_port_handle_t* deviceId) {
501 if (mRecord != 0) {
502 *deviceId = mRecord->getRoutedDeviceId();
503 return NO_ERROR;
504 }
505 return NO_INIT;
506 }
507
addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)508 status_t AudioSource::addAudioDeviceCallback(
509 const sp<AudioSystem::AudioDeviceCallback>& callback) {
510 if (mRecord != 0) {
511 return mRecord->addAudioDeviceCallback(callback);
512 }
513 return NO_INIT;
514 }
515
removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)516 status_t AudioSource::removeAudioDeviceCallback(
517 const sp<AudioSystem::AudioDeviceCallback>& callback) {
518 if (mRecord != 0) {
519 return mRecord->removeAudioDeviceCallback(callback);
520 }
521 return NO_INIT;
522 }
523
getActiveMicrophones(std::vector<media::MicrophoneInfoFw> * activeMicrophones)524 status_t AudioSource::getActiveMicrophones(
525 std::vector<media::MicrophoneInfoFw>* activeMicrophones) {
526 if (mRecord != 0) {
527 return mRecord->getActiveMicrophones(activeMicrophones);
528 }
529 return NO_INIT;
530 }
531
setPreferredMicrophoneDirection(audio_microphone_direction_t direction)532 status_t AudioSource::setPreferredMicrophoneDirection(audio_microphone_direction_t direction) {
533 ALOGV("setPreferredMicrophoneDirection(%d)", direction);
534 if (mRecord != 0) {
535 return mRecord->setPreferredMicrophoneDirection(direction);
536 }
537 return NO_INIT;
538 }
539
setPreferredMicrophoneFieldDimension(float zoom)540 status_t AudioSource::setPreferredMicrophoneFieldDimension(float zoom) {
541 ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
542 if (mRecord != 0) {
543 return mRecord->setPreferredMicrophoneFieldDimension(zoom);
544 }
545 return NO_INIT;
546 }
547
getPortId(audio_port_handle_t * portId) const548 status_t AudioSource::getPortId(audio_port_handle_t *portId) const {
549 if (mRecord != 0) {
550 *portId = mRecord->getPortId();
551 return NO_ERROR;
552 }
553 return NO_INIT;
554 }
555 } // namespace android
556