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

Commit 809b4b7a authored by Mingming Yin's avatar Mingming Yin Committed by Steve Kondik
Browse files

audio: Add support for tunnel mode recording

- Add support for tunnel mode recording.

Change-Id: I95cdfff729affd784141487521c9f2f714221d11
parent 47c98e7e
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -104,6 +105,17 @@ private:

    AudioSource(const AudioSource &);
    AudioSource &operator=(const AudioSource &);

    //additions for tunnel source
public:
    AudioSource(
        audio_source_t inputSource, const sp<MetaData>& meta );

private:
    audio_format_t mFormat;
    String8 mMime;
    int32_t mMaxBufferSize;
    int64_t bufferDurationUs( ssize_t n );
};

}  // namespace android
+20 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -43,6 +44,8 @@ extern const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW;
extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
extern const char *MEDIA_MIMETYPE_AUDIO_FLAC;
extern const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS_LBR;

extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
@@ -57,6 +60,23 @@ extern const char *MEDIA_MIMETYPE_CONTAINER_WVM;
extern const char *MEDIA_MIMETYPE_TEXT_3GPP;
extern const char *MEDIA_MIMETYPE_TEXT_SUBRIP;

extern const char *MEDIA_MIMETYPE_AUDIO_EVRC;

extern const char *MEDIA_MIMETYPE_VIDEO_WMV;
extern const char *MEDIA_MIMETYPE_AUDIO_WMA;
extern const char *MEDIA_MIMETYPE_CONTAINER_ASF;
extern const char *MEDIA_MIMETYPE_VIDEO_DIVX;
extern const char *MEDIA_MIMETYPE_AUDIO_AC3;
extern const char *MEDIA_MIMETYPE_AUDIO_EAC3;
extern const char *MEDIA_MIMETYPE_CONTAINER_AAC;
extern const char *MEDIA_MIMETYPE_CONTAINER_QCP;
extern const char *MEDIA_MIMETYPE_VIDEO_DIVX311;
extern const char *MEDIA_MIMETYPE_VIDEO_DIVX4;
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2;

extern const char *MEDIA_MIMETYPE_CONTAINER_3G2;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS;

}  // namespace android

#endif  // MEDIA_DEFS_H_
+70 −10
Original line number Diff line number Diff line
/*
**
** Copyright 2008, The Android Open Source Project
** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
** Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -185,12 +185,51 @@ status_t AudioRecord::set(
        return BAD_VALUE;
    }

    // validate framecount
    int minFrameCount = 0;
    status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask);
    if (status != NO_ERROR) {
        return status;
    size_t inputBuffSizeInBytes = -1;
    if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &inputBuffSizeInBytes)
            != NO_ERROR) {
        ALOGE("AudioSystem could not query the input buffer size.");
        return NO_INIT;
    }
    ALOGV("AudioRecord::set() inputBuffSizeInBytes = %d", inputBuffSizeInBytes );

    if (inputBuffSizeInBytes == 0) {
        ALOGE("Recording parameters are not supported: sampleRate %d, channelCount %d, format %d",
            sampleRate, channelCount, format);
        return BAD_VALUE;
    }

    // Change for Codec type
    int frameSizeInBytes = 0;
    if(inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION) {
        if (audio_is_linear_pcm(format)) {
             frameSizeInBytes = channelCount * (format == AUDIO_FORMAT_PCM_16_BIT ? sizeof(int16_t)
: sizeof(int8_t));
        } else {
             frameSizeInBytes = channelCount *sizeof(int16_t);
        }
    } else {
        if (format ==AUDIO_FORMAT_AMR_NB) {
             frameSizeInBytes = channelCount * 32; // Full rate framesize
        } else if (format ==AUDIO_FORMAT_EVRC) {
             frameSizeInBytes = channelCount * 23; // Full rate framesize
        } else if (format ==AUDIO_FORMAT_QCELP) {
             frameSizeInBytes = channelCount * 35; // Full rate framesize
        } else if (format ==AUDIO_FORMAT_AAC) {
             frameSizeInBytes = 2048;
        } else if ((format ==AUDIO_FORMAT_PCM_16_BIT) || (format ==AUDIO_FORMAT_PCM_8_BIT)) {
             if (audio_is_linear_pcm(format)) {
                  frameSizeInBytes = channelCount * (format == AUDIO_FORMAT_PCM_16_BIT ? sizeof(int16_t) : sizeof(int8_t));
             } else {
                  frameSizeInBytes = sizeof(int8_t);
             }
        } else if(format == AUDIO_FORMAT_AMR_WB) {
            frameSizeInBytes = channelCount * 61;

        }
    }
    // We use 2* size of input buffer for ping pong use of record buffer.
    int minFrameCount = 2 * inputBuffSizeInBytes / frameSizeInBytes;
    ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);

    if (frameCount == 0) {
@@ -204,7 +243,7 @@ status_t AudioRecord::set(
    }

    // create the IAudioRecord
    status = openRecord_l(sampleRate, format, channelMask,
    status_t status = openRecord_l(sampleRate, format, channelMask,
                        frameCount, input);
    if (status != NO_ERROR) {
        return status;
@@ -269,12 +308,33 @@ uint32_t AudioRecord::frameCount() const

size_t AudioRecord::frameSize() const
{
    if(inputSource() == AUDIO_SOURCE_VOICE_COMMUNICATION) {
        if (audio_is_linear_pcm(mFormat)) {
             return channelCount()*audio_bytes_per_sample(mFormat);
        } else {
            return channelCount()*sizeof(int16_t);
        }
    } else {
        if (format() ==AUDIO_FORMAT_AMR_NB) {
             return channelCount() * 32; // Full rate framesize
        } else if (format() == AUDIO_FORMAT_EVRC) {
             return channelCount() * 23; // Full rate framesize
        } else if (format() == AUDIO_FORMAT_QCELP) {
             return channelCount() * 35; // Full rate framesize
        } else if (format() == AUDIO_FORMAT_AAC) {
            // Not actual framsize but for variable frame rate AAC encoding,
           // buffer size is treated as a frame size
             return 2048;
        } else if(format() == AUDIO_FORMAT_AMR_WB) {
            return channelCount() * 61;
        }
        if (audio_is_linear_pcm(mFormat)) {
            return channelCount()*audio_bytes_per_sample(mFormat);
        } else {
            return sizeof(uint8_t);
        }
    }
}

audio_source_t AudioRecord::inputSource() const
{
+2 −0
Original line number Diff line number Diff line
@@ -41,10 +41,12 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_STATIC_LIBRARIES :=       \
    libstagefright_nuplayer     \
    libstagefright_rtsp         \
    libmedia_helper             \

LOCAL_C_INCLUDES :=                                                 \
    $(call include-path-for, graphics corecg)                       \
    $(TOP)/frameworks/av/media/libstagefright/include               \
    $(TOP)/frameworks/av/include/media                              \
    $(TOP)/frameworks/av/media/libstagefright/rtsp                  \
    $(TOP)/frameworks/av/media/libstagefright/wifi-display          \
    $(TOP)/frameworks/native/include/media/openmax                  \
+41 −1
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "StagefrightRecorder"
#include <utils/Log.h>

#include <media/AudioParameter.h>
#include "StagefrightRecorder.h"

#include <binder/IPCThreadState.h>
@@ -53,6 +53,7 @@
#include <camera/ICamera.h>
#include <camera/CameraParameters.h>
#include <gui/Surface.h>
#include <utils/String8.h>

#include <utils/Errors.h>
#include <sys/types.h>
@@ -855,6 +856,45 @@ status_t StagefrightRecorder::start() {
}

sp<MediaSource> StagefrightRecorder::createAudioSource() {
    bool tunneledSource = false;
    const char *tunnelMime;
    {
        AudioParameter param;
        String8 key("tunneled-input-formats");
        param.add( key, String8("get") );
        String8 valueStr = AudioSystem::getParameters( 0, param.toString());
        AudioParameter result(valueStr);
        int value;
        if ( mAudioEncoder == AUDIO_ENCODER_AMR_NB &&
            result.getInt(String8("AMR"),value) == NO_ERROR ) {
            tunneledSource = true;
            tunnelMime = MEDIA_MIMETYPE_AUDIO_AMR_NB;
        }
        else if ( mAudioEncoder == AUDIO_ENCODER_QCELP &&
            result.getInt(String8("QCELP"),value) == NO_ERROR ) {
            tunneledSource = true;
            tunnelMime = MEDIA_MIMETYPE_AUDIO_QCELP;
        }
        else if ( mAudioEncoder == AUDIO_ENCODER_EVRC &&
            result.getInt(String8("EVRC"),value) == NO_ERROR ) {
            tunneledSource = true;
            tunnelMime = MEDIA_MIMETYPE_AUDIO_EVRC;
        }
    }

    if ( tunneledSource ) {
        sp<AudioSource> audioSource = NULL;
        sp<MetaData> meta = new MetaData;
        meta->setInt32(kKeyChannelCount, mAudioChannels);
        meta->setInt32(kKeySampleRate, mSampleRate);
        meta->setInt32(kKeyBitRate, mAudioBitRate);
        if (mAudioTimeScale > 0) {
            meta->setInt32(kKeyTimeScale, mAudioTimeScale);
        }
        meta->setCString( kKeyMIMEType, tunnelMime );
        audioSource = new AudioSource( mAudioSource, meta);
        return audioSource->initCheck( ) == OK ? audioSource : NULL;
    }
    sp<AudioSource> audioSource =
        new AudioSource(
                mAudioSource,
Loading