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