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