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

Commit dacaa73a authored by Andreas Huber's avatar Andreas Huber
Browse files

Initial check in of stagefright software AAC decoder based on PV source code.

parent 5921fb51
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -50,6 +50,13 @@ LOCAL_SHARED_LIBRARIES := \
        libcutils         \
        libui

ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)

LOCAL_STATIC_LIBRARIES := \
        libstagefright_aacdec

endif

ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
        LOCAL_LDLIBS += -lpthread
endif
+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define LOG_TAG "OMXCodec"
#include <utils/Log.h>

#include "include/AACDecoder.h"
#include "include/ESDS.h"

#include <binder/IServiceManager.h>
@@ -284,6 +285,10 @@ sp<MediaSource> OMXCodec::Create(
    bool success = meta->findCString(kKeyMIMEType, &mime);
    CHECK(success);

    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
        return new AACDecoder(source);
    }

    Vector<String8> matchingCodecs;
    findMatchingCodecs(
            mime, createEncoder, matchComponentName, flags, &matchingCodecs);
+8 −0
Original line number Diff line number Diff line
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

include $(call all-makefiles-under,$(LOCAL_PATH))

endif
+202 −0
Original line number Diff line number Diff line
#include "AACDecoder.h"

#include "../../include/ESDS.h"

#include "pvmp4audiodecoder_api.h"

#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>

namespace android {

AACDecoder::AACDecoder(const sp<MediaSource> &source)
    : mSource(source),
      mStarted(false),
      mBufferGroup(NULL),
      mConfig(new tPVMP4AudioDecoderExternal),
      mDecoderBuf(NULL),
      mLastSeekTimeUs(0),
      mNumSamplesOutput(0),
      mInputBuffer(NULL) {
}

AACDecoder::~AACDecoder() {
    if (mStarted) {
        stop();
    }

    delete mConfig;
    mConfig = NULL;
}

status_t AACDecoder::start(MetaData *params) {
    CHECK(!mStarted);

    mBufferGroup = new MediaBufferGroup;
    mBufferGroup->add_buffer(new MediaBuffer(2048 * 2));

    mConfig->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
    mConfig->aacPlusUpsamplingFactor = 0;
    mConfig->aacPlusEnabled = false;

    int32_t numChannels;
    CHECK(mSource->getFormat()->findInt32(kKeyChannelCount, &numChannels));
    mConfig->desiredChannels = numChannels;

    UInt32 memRequirements = PVMP4AudioDecoderGetMemRequirements();
    mDecoderBuf = malloc(memRequirements);

    CHECK_EQ(PVMP4AudioDecoderInitLibrary(mConfig, mDecoderBuf),
             MP4AUDEC_SUCCESS);

    uint32_t type;
    const void *data;
    size_t size;
    if (mSource->getFormat()->findData(kKeyESDS, &type, &data, &size)) {
        ESDS esds((const char *)data, size);
        CHECK_EQ(esds.InitCheck(), OK);

        const void *codec_specific_data;
        size_t codec_specific_data_size;
        esds.getCodecSpecificInfo(
                &codec_specific_data, &codec_specific_data_size);

        mConfig->pInputBuffer = (UChar *)codec_specific_data;
        mConfig->inputBufferCurrentLength = codec_specific_data_size;
        mConfig->inputBufferMaxLength = 0;
        mConfig->inputBufferUsedLength = 0;
        mConfig->remainderBits = 0;

        mConfig->pOutputBuffer = NULL;
        mConfig->pOutputBuffer_plus = NULL;
        mConfig->repositionFlag = false;

        CHECK_EQ(PVMP4AudioDecoderConfig(mConfig, mDecoderBuf),
                 MP4AUDEC_SUCCESS);
    }

    mSource->start();

    mLastSeekTimeUs = 0;
    mNumSamplesOutput = 0;
    mStarted = true;

    return OK;
}

status_t AACDecoder::stop() {
    CHECK(mStarted);

    if (mInputBuffer) {
        mInputBuffer->release();
        mInputBuffer = NULL;
    }

    free(mDecoderBuf);
    mDecoderBuf = NULL;

    delete mBufferGroup;
    mBufferGroup = NULL;

    mSource->stop();

    mStarted = false;

    return OK;
}

sp<MetaData> AACDecoder::getFormat() {
    sp<MetaData> srcFormat = mSource->getFormat();

    int32_t numChannels;
    int32_t sampleRate;
    CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
    CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));

    sp<MetaData> meta = new MetaData;
    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
    meta->setInt32(kKeyChannelCount, numChannels);
    meta->setInt32(kKeySampleRate, sampleRate);

    return meta;
}

status_t AACDecoder::read(
        MediaBuffer **out, const ReadOptions *options) {
    status_t err;

    *out = NULL;

    int64_t seekTimeUs;
    if (options && options->getSeekTo(&seekTimeUs)) {
        CHECK(seekTimeUs >= 0);

        mNumSamplesOutput = 0;

        if (mInputBuffer) {
            mInputBuffer->release();
            mInputBuffer = NULL;
        }
    } else {
        seekTimeUs = -1;
    }

    if (mInputBuffer == NULL) {
        err = mSource->read(&mInputBuffer, options);

        if (err != OK) {
            return err;
        }

        if (seekTimeUs >= 0) {
            CHECK(mInputBuffer->meta_data()->findInt64(
                        kKeyTime, &mLastSeekTimeUs));

            mNumSamplesOutput = 0;
        }
    }

    MediaBuffer *buffer;
    CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);

    mConfig->pInputBuffer =
        (UChar *)mInputBuffer->data() + mInputBuffer->range_offset();

    mConfig->inputBufferCurrentLength = mInputBuffer->range_length();
    mConfig->inputBufferMaxLength = 0;
    mConfig->inputBufferUsedLength = 0;
    mConfig->remainderBits = 0;

    mConfig->pOutputBuffer = static_cast<Int16 *>(buffer->data());
    mConfig->pOutputBuffer_plus = NULL;
    mConfig->repositionFlag = false;

    CHECK_EQ(PVMP4AudioDecodeFrame(mConfig, mDecoderBuf), MP4AUDEC_SUCCESS);

    buffer->set_range(
            0, mConfig->frameLength * sizeof(int16_t) * mConfig->desiredChannels);

    mInputBuffer->set_range(
            mInputBuffer->range_offset() + mConfig->inputBufferUsedLength,
            mInputBuffer->range_length() - mConfig->inputBufferUsedLength);

    if (mInputBuffer->range_length() == 0) {
        mInputBuffer->release();
        mInputBuffer = NULL;
    }

    buffer->meta_data()->setInt64(
            kKeyTime,
            mLastSeekTimeUs
                + (mNumSamplesOutput * 1000000) / mConfig->samplingRate);

    mNumSamplesOutput += mConfig->frameLength;

    *out = buffer;

    return OK;
}

}  // namespace android
+158 −0
Original line number Diff line number Diff line
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES := \
	analysis_sub_band.cpp \
 	apply_ms_synt.cpp \
 	apply_tns.cpp \
 	buf_getbits.cpp \
 	byte_align.cpp \
 	calc_auto_corr.cpp \
 	calc_gsfb_table.cpp \
 	calc_sbr_anafilterbank.cpp \
 	calc_sbr_envelope.cpp \
 	calc_sbr_synfilterbank.cpp \
 	check_crc.cpp \
 	dct16.cpp \
 	dct64.cpp \
 	decode_huff_cw_binary.cpp \
 	decode_noise_floorlevels.cpp \
 	deinterleave.cpp \
 	digit_reversal_tables.cpp \
 	dst16.cpp \
 	dst32.cpp \
 	dst8.cpp \
 	esc_iquant_scaling.cpp \
 	extractframeinfo.cpp \
 	fft_rx4_long.cpp \
 	fft_rx4_short.cpp \
 	fft_rx4_tables_fxp.cpp \
 	find_adts_syncword.cpp \
 	fwd_long_complex_rot.cpp \
 	fwd_short_complex_rot.cpp \
 	gen_rand_vector.cpp \
 	get_adif_header.cpp \
 	get_adts_header.cpp \
 	get_audio_specific_config.cpp \
 	get_dse.cpp \
 	get_ele_list.cpp \
 	get_ga_specific_config.cpp \
 	get_ics_info.cpp \
 	get_prog_config.cpp \
 	get_pulse_data.cpp \
 	get_sbr_bitstream.cpp \
 	get_sbr_startfreq.cpp \
 	get_sbr_stopfreq.cpp \
 	get_tns.cpp \
 	getfill.cpp \
 	getgroup.cpp \
 	getics.cpp \
 	getmask.cpp \
 	hcbtables_binary.cpp \
 	huffcb.cpp \
 	huffdecode.cpp \
 	hufffac.cpp \
 	huffspec_fxp.cpp \
 	idct16.cpp \
 	idct32.cpp \
 	idct8.cpp \
 	imdct_fxp.cpp \
 	infoinit.cpp \
 	init_sbr_dec.cpp \
 	intensity_right.cpp \
 	inv_long_complex_rot.cpp \
 	inv_short_complex_rot.cpp \
 	iquant_table.cpp \
 	long_term_prediction.cpp \
 	long_term_synthesis.cpp \
 	lt_decode.cpp \
 	mdct_fxp.cpp \
 	mdct_tables_fxp.cpp \
 	mdst.cpp \
 	mix_radix_fft.cpp \
 	ms_synt.cpp \
 	pns_corr.cpp \
 	pns_intensity_right.cpp \
 	pns_left.cpp \
 	ps_all_pass_filter_coeff.cpp \
 	ps_all_pass_fract_delay_filter.cpp \
 	ps_allocate_decoder.cpp \
 	ps_applied.cpp \
 	ps_bstr_decoding.cpp \
 	ps_channel_filtering.cpp \
 	ps_decode_bs_utils.cpp \
 	ps_decorrelate.cpp \
 	ps_fft_rx8.cpp \
 	ps_hybrid_analysis.cpp \
 	ps_hybrid_filter_bank_allocation.cpp \
 	ps_hybrid_synthesis.cpp \
 	ps_init_stereo_mixing.cpp \
 	ps_pwr_transient_detection.cpp \
 	ps_read_data.cpp \
 	ps_stereo_processing.cpp \
 	pulse_nc.cpp \
 	pv_div.cpp \
 	pv_log2.cpp \
 	pv_normalize.cpp \
 	pv_pow2.cpp \
 	pv_sine.cpp \
 	pv_sqrt.cpp \
 	pvmp4audiodecoderconfig.cpp \
 	pvmp4audiodecoderframe.cpp \
 	pvmp4audiodecodergetmemrequirements.cpp \
 	pvmp4audiodecoderinitlibrary.cpp \
 	pvmp4audiodecoderresetbuffer.cpp \
 	q_normalize.cpp \
 	qmf_filterbank_coeff.cpp \
 	sbr_aliasing_reduction.cpp \
 	sbr_applied.cpp \
 	sbr_code_book_envlevel.cpp \
 	sbr_crc_check.cpp \
 	sbr_create_limiter_bands.cpp \
 	sbr_dec.cpp \
 	sbr_decode_envelope.cpp \
 	sbr_decode_huff_cw.cpp \
 	sbr_downsample_lo_res.cpp \
 	sbr_envelope_calc_tbl.cpp \
 	sbr_envelope_unmapping.cpp \
 	sbr_extract_extended_data.cpp \
 	sbr_find_start_andstop_band.cpp \
 	sbr_generate_high_freq.cpp \
 	sbr_get_additional_data.cpp \
 	sbr_get_cpe.cpp \
 	sbr_get_dir_control_data.cpp \
 	sbr_get_envelope.cpp \
 	sbr_get_header_data.cpp \
 	sbr_get_noise_floor_data.cpp \
 	sbr_get_sce.cpp \
 	sbr_inv_filt_levelemphasis.cpp \
 	sbr_open.cpp \
 	sbr_read_data.cpp \
 	sbr_requantize_envelope_data.cpp \
 	sbr_reset_dec.cpp \
 	sbr_update_freq_scale.cpp \
 	set_mc_info.cpp \
 	sfb.cpp \
 	shellsort.cpp \
 	synthesis_sub_band.cpp \
 	tns_ar_filter.cpp \
 	tns_decode_coef.cpp \
 	tns_inv_filter.cpp \
 	trans4m_freq_2_time_fxp.cpp \
 	trans4m_time_2_freq_fxp.cpp \
 	unpack_idx.cpp \
 	window_tables_fxp.cpp \
 	pvmp4setaudioconfig.cpp \
        AACDecoder.cpp

LOCAL_CFLAGS := -DAAC_PLUS -DHQ_SBR -DPARAMETRICSTEREO -DOSCL_IMPORT_REF= -DOSCL_EXPORT_REF= -DOSCL_UNUSED_ARG=

LOCAL_C_INCLUDES := frameworks/base/media/libstagefright/include

LOCAL_SHARED_LIBRARIES := \
        libstagefright \
        libutils

LOCAL_MODULE := libstagefright_aacdec

include $(BUILD_STATIC_LIBRARY)
Loading