直接帖代码,主要分三个步骤。
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(); }