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

Commit 69d60c13 authored by Dongwon Kang's avatar Dongwon Kang Committed by Gerrit Code Review
Browse files

Merge "Remove unused IMediaSource Implementation, AACEncoder"

parents 67b97497 725cad09
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -107,7 +107,6 @@ cc_library_shared {
    static_libs: [
        "libstagefright_color_conversion",
        "libyuv_static",
        "libstagefright_aacenc",
        "libstagefright_matroska",
        "libstagefright_mediafilter",
        "libstagefright_omx_utils",
+0 −332
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "AACEncoder"
#include <utils/Log.h>

#include "AACEncoder.h"
#include "voAAC.h"
#include "cmnMemory.h"

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>

namespace android {

AACEncoder::AACEncoder(const sp<IMediaSource> &source, const sp<MetaData> &meta)
    : mSource(source),
      mMeta(meta),
      mStarted(false),
      mBufferGroup(NULL),
      mInputBuffer(NULL),
      mInputFrame(NULL),
      mEncoderHandle(NULL),
      mApiHandle(NULL),
      mMemOperator(NULL) {
}

status_t AACEncoder::initCheck() {
    CHECK(mApiHandle == NULL && mEncoderHandle == NULL);
    CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));
    CHECK(mMeta->findInt32(kKeyChannelCount, &mChannels));
    CHECK(mChannels <= 2 && mChannels >= 1);
    CHECK(mMeta->findInt32(kKeyBitRate, &mBitRate));

    mApiHandle = new VO_AUDIO_CODECAPI;
    CHECK(mApiHandle);

    if (VO_ERR_NONE != voGetAACEncAPI(mApiHandle)) {
        ALOGE("Failed to get api handle");
        return UNKNOWN_ERROR;
    }

    mMemOperator = new VO_MEM_OPERATOR;
    CHECK(mMemOperator != NULL);
    mMemOperator->Alloc = cmnMemAlloc;
    mMemOperator->Copy = cmnMemCopy;
    mMemOperator->Free = cmnMemFree;
    mMemOperator->Set = cmnMemSet;
    mMemOperator->Check = cmnMemCheck;

    VO_CODEC_INIT_USERDATA userData;
    memset(&userData, 0, sizeof(userData));
    userData.memflag = VO_IMF_USERMEMOPERATOR;
    userData.memData = (VO_PTR) mMemOperator;
    if (VO_ERR_NONE != mApiHandle->Init(&mEncoderHandle, VO_AUDIO_CodingAAC, &userData)) {
        ALOGE("Failed to init AAC encoder");
        return UNKNOWN_ERROR;
    }
    if (OK != setAudioSpecificConfigData()) {
        ALOGE("Failed to configure AAC encoder");
        return UNKNOWN_ERROR;
    }

    // Configure AAC encoder$
    AACENC_PARAM params;
    memset(&params, 0, sizeof(params));
    params.sampleRate = mSampleRate;
    params.bitRate = mBitRate;
    params.nChannels = mChannels;
    params.adtsUsed = 0;  // We add adts header in the file writer if needed.
    if (VO_ERR_NONE != mApiHandle->SetParam(mEncoderHandle, VO_PID_AAC_ENCPARAM,  &params)) {
        ALOGE("Failed to set AAC encoder parameters");
        return UNKNOWN_ERROR;
    }

    return OK;
}

static status_t getSampleRateTableIndex(int32_t sampleRate, int32_t &index) {
    static const int32_t kSampleRateTable[] = {
        96000, 88200, 64000, 48000, 44100, 32000,
        24000, 22050, 16000, 12000, 11025, 8000
    };
    const int32_t tableSize = sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]);
    for (int32_t i = 0; i < tableSize; ++i) {
        if (sampleRate == kSampleRateTable[i]) {
            index = i;
            return OK;
        }
    }

    ALOGE("Sampling rate %d bps is not supported", sampleRate);
    return UNKNOWN_ERROR;
}

status_t AACEncoder::setAudioSpecificConfigData() {
    ALOGV("setAudioSpecificConfigData: %d hz, %d bps, and %d channels",
         mSampleRate, mBitRate, mChannels);

    int32_t index = 0;
    CHECK_EQ((status_t)OK, getSampleRateTableIndex(mSampleRate, index));
    if (mChannels > 2 || mChannels <= 0) {
        ALOGE("Unsupported number of channels(%d)", mChannels);
        return UNKNOWN_ERROR;
    }

    // OMX_AUDIO_AACObjectLC
    mAudioSpecificConfigData[0] = ((0x02 << 3) | (index >> 1));
    mAudioSpecificConfigData[1] = ((index & 0x01) << 7) | (mChannels << 3);
    return OK;
}

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

status_t AACEncoder::start(MetaData *params) {
    if (mStarted) {
        ALOGW("Call start() when encoder already started");
        return OK;
    }

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

    CHECK_EQ((status_t)OK, initCheck());

    mNumInputSamples = 0;
    mAnchorTimeUs = 0;
    mFrameCount = 0;

    mInputFrame = new int16_t[mChannels * kNumSamplesPerFrame];
    CHECK(mInputFrame != NULL);

    status_t err = mSource->start(params);
    if (err != OK) {
         ALOGE("AudioSource is not available");
        return err;
    }

    mStarted = true;

    return OK;
}

status_t AACEncoder::stop() {
    if (mInputBuffer) {
        mInputBuffer->release();
        mInputBuffer = NULL;
    }

    delete mBufferGroup;
    mBufferGroup = NULL;

    if (mInputFrame) {
        delete[] mInputFrame;
        mInputFrame = NULL;
    }

    if (!mStarted) {
        ALOGW("Call stop() when encoder has not started");
        return ERROR_END_OF_STREAM;
    }

    mSource->stop();
    if (mEncoderHandle) {
        CHECK_EQ((VO_U32)VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle));
        mEncoderHandle = NULL;
    }
    delete mApiHandle;
    mApiHandle = NULL;

    delete mMemOperator;
    mMemOperator = NULL;

    mStarted = false;

    return OK;
}

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

    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);

    int64_t durationUs;
    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
        mMeta->setInt64(kKeyDuration, durationUs);
    }

    mMeta->setCString(kKeyDecoderComponent, "AACEncoder");

    return mMeta;
}

status_t AACEncoder::read(
        MediaBuffer **out, const ReadOptions *options) {
    *out = NULL;

    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode));

    MediaBuffer *buffer;
    CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), (status_t)OK);
    uint8_t *outPtr = (uint8_t *)buffer->data();
    bool readFromSource = false;
    int64_t wallClockTimeUs = -1;

    if (mFrameCount == 0) {
        memcpy(outPtr, mAudioSpecificConfigData, 2);
        buffer->set_range(0, 2);
        buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
        *out = buffer;
        ++mFrameCount;
        return OK;
    } else if (mFrameCount == 1) {
        buffer->meta_data()->setInt32(kKeyIsCodecConfig, false);
    }

    const int32_t nSamples = mChannels * kNumSamplesPerFrame;
    while (mNumInputSamples < nSamples) {
        if (mInputBuffer == NULL) {
            if (mSource->read(&mInputBuffer, options) != OK) {
                if (mNumInputSamples == 0) {
                    buffer->release();
                    return ERROR_END_OF_STREAM;
                }
                memset(&mInputFrame[mNumInputSamples],
                       0,
                       sizeof(int16_t) * (nSamples - mNumInputSamples));
                mNumInputSamples = 0;
                break;
            }

            size_t align = mInputBuffer->range_length() % sizeof(int16_t);
            CHECK_EQ(align, (size_t)0);

            int64_t timeUs;
            if (mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs)) {
                wallClockTimeUs = timeUs;
            }
            if (mInputBuffer->meta_data()->findInt64(kKeyAnchorTime, &timeUs)) {
                mAnchorTimeUs = timeUs;
            }
            readFromSource = true;
        } else {
            readFromSource = false;
        }
        size_t copy = (nSamples - mNumInputSamples) * sizeof(int16_t);

        if (copy > mInputBuffer->range_length()) {
            copy = mInputBuffer->range_length();
        }

        memcpy(&mInputFrame[mNumInputSamples],
               (const uint8_t *) mInputBuffer->data()
                    + mInputBuffer->range_offset(),
               copy);

        mInputBuffer->set_range(
               mInputBuffer->range_offset() + copy,
               mInputBuffer->range_length() - copy);

        if (mInputBuffer->range_length() == 0) {
            mInputBuffer->release();
            mInputBuffer = NULL;
        }
        mNumInputSamples += copy / sizeof(int16_t);
        if (mNumInputSamples >= nSamples) {
            mNumInputSamples %= nSamples;
            break;
        }
    }

    VO_CODECBUFFER inputData;
    memset(&inputData, 0, sizeof(inputData));
    inputData.Buffer = (unsigned char*) mInputFrame;
    inputData.Length = nSamples * sizeof(int16_t);
    CHECK((VO_U32)VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData));

    VO_CODECBUFFER outputData;
    memset(&outputData, 0, sizeof(outputData));
    VO_AUDIO_OUTPUTINFO outputInfo;
    memset(&outputInfo, 0, sizeof(outputInfo));

    VO_U32 ret = VO_ERR_NONE;
    size_t nOutputBytes = 0;
    do {
        outputData.Buffer = outPtr;
        outputData.Length = buffer->size() - nOutputBytes;
        ret = mApiHandle->GetOutputData(mEncoderHandle, &outputData, &outputInfo);
        if (ret == VO_ERR_NONE) {
            outPtr += outputData.Length;
            nOutputBytes += outputData.Length;
        }
    } while (ret != VO_ERR_INPUT_BUFFER_SMALL);
    buffer->set_range(0, nOutputBytes);

    int64_t mediaTimeUs =
        ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate;

    buffer->meta_data()->setInt64(kKeyTime, mAnchorTimeUs + mediaTimeUs);
    if (readFromSource && wallClockTimeUs != -1) {
        buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs);
    }
    ++mFrameCount;

    *out = buffer;
    return OK;
}

}  // namespace android
+0 −144
Original line number Diff line number Diff line
cc_library_static {
    name: "libstagefright_aacenc",

    srcs: [
        "basic_op/basicop2.c",
        "basic_op/oper_32b.c",

        "AACEncoder.cpp",
        "src/aac_rom.c",
        "src/aacenc.c",
        "src/aacenc_core.c",
        "src/adj_thr.c",
        "src/band_nrg.c",
        "src/bit_cnt.c",
        "src/bitbuffer.c",
        "src/bitenc.c",
        "src/block_switch.c",
        "src/channel_map.c",
        "src/dyn_bits.c",
        "src/grp_data.c",
        "src/interface.c",
        "src/line_pe.c",
        "src/ms_stereo.c",
        "src/pre_echo_control.c",
        "src/psy_configuration.c",
        "src/psy_main.c",
        "src/qc_main.c",
        "src/quantize.c",
        "src/sf_estim.c",
        "src/spreading.c",
        "src/stat_bits.c",
        "src/tns.c",
        "src/transform.c",
        "src/memalign.c",
    ],

    arch: {
        arm: {
            srcs: [
                "src/asm/ARMV5E/AutoCorrelation_v5.s",
                "src/asm/ARMV5E/band_nrg_v5.s",
                "src/asm/ARMV5E/CalcWindowEnergy_v5.s",
                "src/asm/ARMV5E/PrePostMDCT_v5.s",
                "src/asm/ARMV5E/R4R8First_v5.s",
                "src/asm/ARMV5E/Radix4FFT_v5.s",
            ],

            cflags: [
                "-DARMV5E",
                "-DARM_INASM",
                "-DARMV5_INASM",
            ],

            local_include_dirs: ["src/asm/ARMV5E"],

            instruction_set: "arm",

            neon: {
                exclude_srcs: [
                    "src/asm/ARMV5E/PrePostMDCT_v5.s",
                    "src/asm/ARMV5E/R4R8First_v5.s",
                    "src/asm/ARMV5E/Radix4FFT_v5.s",
                ],
                srcs: [
                    "src/asm/ARMV7/PrePostMDCT_v7.s",
                    "src/asm/ARMV7/R4R8First_v7.s",
                    "src/asm/ARMV7/Radix4FFT_v7.s",
                ],

                cflags: [
                    "-DARMV7Neon",
                    "-DARMV6_INASM",
                ],

                local_include_dirs: ["src/asm/ARMV7"],
            },
        },
    },

    // libstagefright links this static library, so it probably isn't appropriate to
    // link libstagefright.  However, this library includes libstagefright headers,
    // and needs libbinder to be able to do so correctly.
    shared_libs: [
        "libbinder",
        "libstagefright_enc_common",
    ],

    include_dirs: [
        "frameworks/av/include",
        "frameworks/av/media/libstagefright/include",
    ],

    local_include_dirs: [
        "src",
        "inc",
        "basic_op",
    ],

    cflags: ["-Werror"],

    sanitize: {
        misc_undefined: [
            "signed-integer-overflow",
            "unsigned-integer-overflow",
        ],
    },

}

//###############################################################################

cc_library_shared {
    name: "libstagefright_soft_aacenc",

@@ -141,36 +30,3 @@ cc_library_shared {
        "liblog",
    ],
}

cc_library_shared {
    name: "libstagefright_soft_aacenc_visualon",

    srcs: ["SoftAACEncoder.cpp"],

    include_dirs: [
        "frameworks/av/media/libstagefright/include",
        "frameworks/native/include/media/openmax",
    ],

    cflags: [
        "-DOSCL_IMPORT_REF=",
        "-Werror",
    ],

    sanitize: {
        misc_undefined: [
            "signed-integer-overflow",
            "unsigned-integer-overflow",
        ],
    },

    static_libs: ["libstagefright_aacenc"],

    shared_libs: [
        "libstagefright_omx",
        "libstagefright_foundation",
        "libutils",
        "liblog",
        "libstagefright_enc_common",
    ],
}
+0 −283
Original line number Diff line number Diff line
/*
 ** Copyright 2003-2010, VisualOn, Inc.
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
/*******************************************************************************
	File:		AAC_E_SAMPLES.h

	Content:	sample code for AAC encoder

*******************************************************************************/

#include		<dlfcn.h>
#include		<stdio.h>
#include		<stdlib.h>
#include		<string.h>
#include		<time.h>
#include		"voAAC.h"
#include		"cmnMemory.h"

#define  VO_AAC_E_OUTPUT	  1
#define READ_SIZE	(1024*8)
unsigned char outBuf[1024*8];
unsigned char inBuf[READ_SIZE];

const char* HelpString =
"VisualOn AAC encoder Usage:\n"
"voAACEncTest -if <inputfile.pcm> -of <outputfile.aac> -sr <samplerate> -ch <channel> -br <bitrate> -adts <adts> \n"
"-if input file name \n"
"-of output file name \n"
"-sr input pcm samplerate, default 44100 \n"
"-ch input pcm channel, default 2 channel \n"
"-br encoded aac bitrate, default 64000 * (samplerate/100)*channel/441(480)\n"
"-adts add or no adts header, default add adts header\n"
"For example: \n"
"./voAACEncTest -if raw.pcm -of raw.aac -sr 44100 -ch 2 -br 128000\n";

static int parsecmdline(int argc, char **argv,char  **input_filename, char  **output_filename, AACENC_PARAM *param)
{
	// notice that:
	// bitRate/nChannels > 8000
	// bitRate/nChannels < 160000
	// bitRate/nChannels < sampleRate*6
	param->adtsUsed = 1;
	param->bitRate = 0;
	param->nChannels = 2;
	param->sampleRate = 44100;

	if(argc < 5 || argc > 13)
	{
		return -1;
	}

	argc--;
	argv++;
	while (argc > 0)
	{
		if (!strcmp(*argv, "-if"))
		{
			argv++;
			argc--;
			*input_filename = *argv;
		}
		else if (!strcmp(*argv, "-of"))
		{
			argv++;
			argc--;
			*output_filename = *argv;
		}
		else if (!strcmp(*argv, "-sr"))
		{
			argv++;
			argc--;
			param->sampleRate = atoi(*argv);
		}
		else if (!strcmp(*argv, "-ch"))
		{
			argv++;
			argc--;
			param->nChannels = atoi(*argv);
		}
		else if (!strcmp(*argv, "-br"))
		{
			argv++;
			argc--;
			param->bitRate = atoi(*argv);
		}
		else if(!strcmp(*argv, "-adts"))
		{
			argv++;
			argc--;
			param->adtsUsed = atoi(*argv);
		}
		else
		{
			return -1;
		}

		argv++;
		argc--;
	}

	if(param->bitRate == 0)
	{
		int scale = 441;
		if(param->sampleRate%8000 == 0)
			scale = 480;
		param->bitRate = 640*param->nChannels*param->sampleRate/scale;
	}

	return 0;
}

int ReadFile2Buf(FILE* infile,unsigned char* dest,int readSize)
{
	int readBytes = 0;
	readBytes = fread(dest, 1, readSize, infile);
	return readBytes;
}

typedef int (VO_API * VOGETAUDIODECAPI) (VO_AUDIO_CODECAPI * pDecHandle);

int main(int argc, char **argv)
{
	FILE						*infile, *outfile;
	int							t1, t2;
	VO_AUDIO_CODECAPI			AudioAPI;
	VO_MEM_OPERATOR				moper;
	VO_CODEC_INIT_USERDATA		useData;
	VO_HANDLE					hCodec;
	VO_CODECBUFFER				inData;
	VO_CODECBUFFER				outData;
	VO_AUDIO_OUTPUTINFO			outInfo;
    int							firstWrite = 1;
	int							eofFile = 0;
	int							*info=(int*)inBuf;
	int							bytesLeft, nRead;
	int							EncoderdFrame = 0;
	int							total = 0;
	int							isOutput = 1;
	int							returnCode;
	AACENC_PARAM				aacpara;
	void						*handle;
	void						*pfunc;
	VOGETAUDIODECAPI			pGetAPI;
	const char					*infileName = NULL;
    const char					*outfileName = NULL;

	returnCode = parsecmdline(argc,argv, &infileName, &outfileName, &aacpara);
	if(returnCode)
	{
		printf("%s", HelpString);
		return 0;
	}

	/* open input file */
	infile = fopen(infileName, "rb");
	if (!infile) {
		printf("Open input file fail...");
		return -1;
	}

	/* open output file */
	if(isOutput)
	{
		outfile = fopen(outfileName, "wb");
		if (!outfile) {
			printf("Open output file fail...");
			return -1;
		}
	}
	// set memory operators;
	moper.Alloc = cmnMemAlloc;
	moper.Copy = cmnMemCopy;
	moper.Free = cmnMemFree;
	moper.Set = cmnMemSet;
	moper.Check = cmnMemCheck;
	useData.memflag = VO_IMF_USERMEMOPERATOR;
	useData.memData = (VO_PTR)(&moper);
	// open encoder dll;
	handle = dlopen("libstagefright.so", RTLD_NOW);
	if(handle == 0)
	{
		printf("open dll error......");
		return -1;
	}
	// Get API;
	pfunc = dlsym(handle, "voGetAACEncAPI");
	if(pfunc == 0)
	{
		printf("open function error......");
		return -1;
	}
	pGetAPI = (VOGETAUDIODECAPI)pfunc;
	returnCode  = pGetAPI(&AudioAPI);
	if(returnCode)
		return -1;


//#######################################   Init Encoding Section   #########################################
	returnCode = AudioAPI.Init(&hCodec, VO_AUDIO_CodingAAC, &useData);
	if(returnCode < 0)
	{
		printf("#### VOI_Error2:fail to initialize the Encoderr###\n");
		return -1;
	}

	returnCode = AudioAPI.SetParam(hCodec, VO_PID_AAC_ENCPARAM, &aacpara);

	inData.Buffer = inBuf;
	bytesLeft = ReadFile2Buf(infile,inData.Buffer,READ_SIZE);

//#######################################    Encoding Section   #########################################

	do {

		inData.Length    = bytesLeft;
		outData.Buffer   = outBuf;
		outData.Length = 1024*8;

		t1 = clock();

		returnCode = AudioAPI.SetInputData(hCodec,&inData);

		do {
			outData.Buffer   = outBuf;
			outData.Length = 1024*8;

			returnCode = AudioAPI.GetOutputData(hCodec,&outData, &outInfo);

			if(returnCode == 0)
				EncoderdFrame++;
			if(returnCode == VO_ERR_LICENSE_ERROR)
				break;

#if VO_AAC_E_OUTPUT
			if (isOutput && returnCode == 0)
			{
				fwrite(outData.Buffer, 1, outData.Length, outfile);
			}
#endif
		} while(returnCode != (VO_ERR_INPUT_BUFFER_SMALL));

		if(returnCode == VO_ERR_LICENSE_ERROR)
			break;

		t2 = clock();
		total += t2 - t1;

		if (!eofFile) {
			nRead = ReadFile2Buf(infile, inBuf,READ_SIZE);
			bytesLeft = nRead;
			inData.Buffer = inBuf;
			if (feof(infile))
				eofFile = 1;
		}

	} while (!eofFile && returnCode);


//################################################  End Encoding Section  #######################################################
	returnCode = AudioAPI.Uninit(hCodec);

	fclose(infile);
	if (outfile)
    {
        fclose(outfile);
    }
	dlclose(handle);
	return 0;
}

+0 −18
Original line number Diff line number Diff line
cc_binary {
    name: "AACEncTest",

    srcs: ["AAC_E_SAMPLES.c"],

    arch: {
        arm: {
            instruction_set: "arm",
        },
    },

    shared_libs: [
        "libstagefright",
        "libdl",
    ],

    static_libs: ["libstagefright_enc_common"],
}
Loading