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