使用C++调用MediaCodec进行音频硬编码(PCM->AAC)

直接帖代码,主要分三个步骤。 

1、初始化编码器并启动编码

mLooper = new ALooper;
mLooper->setName("AudioEncoder_looper");
mLooper->start(false);
mCodec = MediaCodec::CreateByType(mLooper, "audio/mp4a-latm", true);
mLooper->registerHandler(this);
sp<AMessage> format = new AMessage;
format->setString("mime", "audio/mp4a-latm");
format->setInt32("aac-profile", OMX_AUDIO_AACObjectLC);
format->setInt32("channel-count", 2);
format->setInt32("sample-rate", 48000);
format->setInt32("bitrate", 48000* 2 * 2);
format->setInt32("max-input-size", 64*1024);
format->setInt32("priority", 0 );
Codec->configure(format, NULL, NULL, MediaCodec::CONFIGURE_FLAG_ENCODE);
mCodec->start();

2、输入PCM数据,得到AAC数据

int32_t err = mCodec->dequeueInputBuffer(&inIndex, 2000);
if(err != OK) {
    FLOGE("codec->dequeueInputBuffer inIdex=%zu, err=%d", inIndex, err);
    return;
}

sp<MediaCodecBuffer> inBuffer;
err = mCodec->getInputBuffer(inIndex, &inBuffer);
if(err != OK) {
    FLOGE("codec->getInputBuffer inIdex=%zu, err=%d", inIndex, err);
    return;
}
inBuffer->setRange(0, retLen * 4);
memcpy(inBuffer->data(), pcmData,  retLen * 4);//pcmData为需要编码的pcm数据
err = mCodec->queueInputBuffer(inIndex, 0, retLen * 4, ptsUsec, 0);
if(err != OK) {
    FLOGE("codec->queueInputBuffer inIdex=%zu, err=%d", inIndex, err);
    return;
}
//output data
err = mCodec->dequeueOutputBuffer(&outIndex, &offset, &size, &ptsUsec, &flags, 2000);
switch (err) {
    case OK:
        if (size != 0) {
            sp<ABuffer> buffer = ABuffer::CreateAsCopy(outBuffers[outIndex]->data(), outBuffers[outIndex]->size());
            //TODO::buffer中含有编码后的AAC数据
        }
        err = mCodec->releaseOutputBuffer(outIndex);
        break;
    case INFO_OUTPUT_BUFFERS_CHANGED:
        FLOGE("AudioEncoder INFO_OUTPUT_BUFFERS_CHANGED");
        err = mCodec->getOutputBuffers(&outBuffers);
        break;
    case -EAGAIN:
        //ALOGV("Got -EAGAIN, looping");
        break;
    default:
        FLOGW("codec->dequeueOutputBuffer err=%d", err);
        break;
}

3、停止编码

if(mCodec!=nullptr){
    mCodec->stop();
    mCodec->release();
    mCodec = nullptr;
}
if(mLooper!=nullptr){
    mLooper->unregisterHandler(id());
    mLooper->stop();
}

猜你喜欢

转载自blog.csdn.net/XiaoKing2008/article/details/120564804