Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 082830f9 authored by Andreas Huber's avatar Andreas Huber
Browse files

Prepare for transmitting audio through AudioSource.

AudioSource can now be configured to output buffers timestamped based
on looper time (absolute) instead of based on systemTime() relative to
start time.

Change-Id: I8eca42648eb50033ac4aafbe5daac64a98a40690
parent e05a6794
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -31,11 +31,12 @@ namespace android {
class AudioRecord;

struct AudioSource : public MediaSource, public MediaBufferObserver {
    // Note that the "channels" parameter is _not_ the number of channels,
    // but a bitmask of audio_channels_t constants.
    // Note that the "channels" parameter _is_ the number of channels,
    // _not_ a bitmask of audio_channels_t constants.
    AudioSource(
            audio_source_t inputSource, uint32_t sampleRate,
            uint32_t channels = AUDIO_CHANNEL_IN_MONO);
            audio_source_t inputSource,
            uint32_t sampleRate,
            uint32_t channels = 1);

    status_t initCheck() const;

@@ -49,9 +50,15 @@ struct AudioSource : public MediaSource, public MediaBufferObserver {
    virtual status_t read(
            MediaBuffer **buffer, const ReadOptions *options = NULL);

    status_t dataCallbackTimestamp(const AudioRecord::Buffer& buffer, int64_t timeUs);
    status_t dataCallback(const AudioRecord::Buffer& buffer);
    virtual void signalBufferReturned(MediaBuffer *buffer);

    // If useLooperTime == true, buffers will carry absolute timestamps
    // as returned by ALooper::GetNowUs(), otherwise systemTime() is used
    // and buffers contain timestamps relative to start time.
    // The default is to _not_ use looper time.
    void setUseLooperTime(bool useLooperTime);

protected:
    virtual ~AudioSource();

@@ -87,6 +94,8 @@ private:

    List<MediaBuffer * > mBuffersReceived;

    bool mUseLooperTime;

    void trackMaxAmplitude(int16_t *data, int nSamples);

    // This is used to raise the volume from mute to the
+18 −5
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <cutils/properties.h>
#include <stdlib.h>

@@ -33,7 +34,7 @@ static void AudioRecordCallbackFunction(int event, void *user, void *info) {
    AudioSource *source = (AudioSource *) user;
    switch (event) {
        case AudioRecord::EVENT_MORE_DATA: {
            source->dataCallbackTimestamp(*((AudioRecord::Buffer *) info), systemTime() / 1000);
            source->dataCallback(*((AudioRecord::Buffer *) info));
            break;
        }
        case AudioRecord::EVENT_OVERRUN: {
@@ -53,7 +54,8 @@ AudioSource::AudioSource(
      mSampleRate(sampleRate),
      mPrevSampleTimeUs(0),
      mNumFramesReceived(0),
      mNumClientOwnedBuffers(0) {
      mNumClientOwnedBuffers(0),
      mUseLooperTime(false) {

    ALOGV("sampleRate: %d, channelCount: %d", sampleRate, channelCount);
    CHECK(channelCount == 1 || channelCount == 2);
@@ -100,6 +102,12 @@ status_t AudioSource::initCheck() const {
    return mInitCheck;
}

void AudioSource::setUseLooperTime(bool useLooperTime) {
    CHECK(!mStarted);

    mUseLooperTime = useLooperTime;
}

status_t AudioSource::start(MetaData *params) {
    Mutex::Autolock autoLock(mLock);
    if (mStarted) {
@@ -271,8 +279,10 @@ void AudioSource::signalBufferReturned(MediaBuffer *buffer) {
    return;
}

status_t AudioSource::dataCallbackTimestamp(
        const AudioRecord::Buffer& audioBuffer, int64_t timeUs) {
status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
    int64_t timeUs =
        mUseLooperTime ? ALooper::GetNowUs() : (systemTime() / 1000ll);

    ALOGV("dataCallbackTimestamp: %lld us", timeUs);
    Mutex::Autolock autoLock(mLock);
    if (!mStarted) {
@@ -290,12 +300,15 @@ status_t AudioSource::dataCallbackTimestamp(
    if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
        mInitialReadTimeUs = timeUs;
        // Initial delay
        if (mStartTimeUs > 0) {
        if (mUseLooperTime) {
            mStartTimeUs = timeUs;
        } else if (mStartTimeUs > 0) {
            mStartTimeUs = timeUs - mStartTimeUs;
        } else {
            // Assume latency is constant.
            mStartTimeUs += mRecord->latency() * 1000;
        }

        mPrevSampleTimeUs = mStartTimeUs;
    }

+27 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/AudioSource.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
@@ -649,6 +650,32 @@ status_t WifiDisplaySource::PlaybackSession::setupPacketizer() {
    mTracks.add(index, new Track(converter));
#endif

#if 0
    sp<AudioSource> audioSource = new AudioSource(
            AUDIO_SOURCE_MIC,
            48000 /* sampleRate */,
            2 /* channelCount */);  // XXX AUDIO_CHANNEL_IN_STEREO?

    CHECK_EQ((status_t)OK, audioSource->initCheck());

    audioSource->setUseLooperTime(true);

    index = mSerializer->addSource(audioSource);
    CHECK_GE(index, 0);

    sp<AMessage> audioFormat;
    err = convertMetaDataToMessage(audioSource->getFormat(), &audioFormat);
    CHECK_EQ(err, (status_t)OK);

    sp<AMessage> audioNotify = new AMessage(kWhatConverterNotify, id());
    audioNotify->setSize("trackIndex", index);

    converter = new Converter(audioNotify, mCodecLooper, audioFormat);
    looper()->registerHandler(converter);

    mTracks.add(index, new Track(converter));
#endif

    return OK;
}