|
发表于 2016-3-16 11:49:51
只看该作者
板凳
再附上音频解码的核心代码吧![mw_shl_code=c,false]static int audio_decoder_init(StagefrightContext *s, struct audio_config audio_cfg){
#ifdef AUDIO_DECODER
//#define PCM_FILE_PLAY_DEBUG
#ifdef PCM_FILE_PLAY_DEBUG
audio_pcm_play(s);
return 0;
#endif
int ret = 0;
sp<MetaData> meta;
const char* mimetype;
int32_t channel_configuration;
printf("%s_%d\n", __FUNCTION__, __LINE__);
#if (defined OMXCODEC)
meta = new MetaData;
if (meta == NULL) {
printf("cannot allocate MetaData");
return -1;
}
if(audio_cfg.stream_type == AUDIO_MP3)
{
mimetype = MEDIA_MIMETYPE_AUDIO_MPEG;
meta->setCString(kKeyMIMEType, mimetype);
}
else if(audio_cfg.stream_type == AUDIO_AAC_ADTS)
{
mimetype = MEDIA_MIMETYPE_AUDIO_AAC;
meta->setCString(kKeyMIMEType, mimetype);
meta->setInt32(kKeyIsADTS, 1);
meta->setInt32(kKeyAACProfile, 0x0002);
}
s->mSampleRate = audio_cfg.sampling_frequency;
channel_configuration = audio_cfg.channel_configuration;
meta->setInt32(kKeySampleRate, s->mSampleRate);
meta->setInt32(kKeyChannelCount, channel_configuration);
s->mAudioSource = new sp<MediaSource>();
*s->mAudioSource = new CStageFrightAudioSource(s, meta);
if (s->mAudioSource == NULL) {
s->mAudioSource = NULL;
printf("Cannot obtain source / mClient");
return -1;
}
if (s->mClient.connect() != OK) {
printf("Cannot connect OMX mClient\n");
ret = -1;
goto fail;
}
s->mAudioDecoder= new sp<MediaSource>();
printf("[%s]@OMXCodec::Create____________________________START\n", __FUNCTION__);
*s->mAudioDecoder = OMXCodec::Create(s->mClient.interface(),
meta,
false,
*s->mAudioSource,
NULL,
OMXCodec::kSoftwareCodecsOnly,
NULL);
if (!(s->mAudioDecoder != NULL && (*s->mAudioDecoder)->start() == OK)) {
printf("[%s]@Cannot start decoder\n", __FUNCTION__);
ret = -1;
s->mClient.disconnect();
s->mAudioSource = NULL;
s->mAudioDecoder = NULL;
goto fail;
}
printf("[%s]@OMXCodec::Create____________________________END\n", __FUNCTION__);
fail:
return ret;
#elif (defined ACODEC)
sp<AMessage> format;
format = new AMessage;
if(format == NULL) {
printf("cannot allocate format\n");
return -1;
}
if(audio_cfg.stream_type == AUDIO_MP3)
{
mimetype = MEDIA_MIMETYPE_AUDIO_MPEG;
format->setString("mime", mimetype);
s->mSampleRate = audio_cfg.sampling_frequency;
}
else if(audio_cfg.stream_type == AUDIO_AAC_ADTS)
{
mimetype = MEDIA_MIMETYPE_AUDIO_AAC;
format->setString("mime", mimetype);
s->mSampleRate = audio_cfg.sampling_frequency/2;
format->setInt32("is-adts", 1);
format->setInt32("aac-profile", 0x0002);
}
channel_configuration = audio_cfg.channel_configuration;
format->setInt32("sample-rate", s->mSampleRate);
format->setInt32("channel-count", channel_configuration);
printf("[%s]@ACodec::Create____________________________START\n", __FUNCTION__);
sp<ALooper> mLooper = new ALooper;
mLooper->setName("MediaCodec_Adio_looper");
mLooper->start(
false, // runOnCallingThread
false, // canCallJava
PRIORITY_FOREGROUND);
s->mACodecAudioDecoder = MediaCodec::CreateByType(
mLooper, mimetype, false /* encoder */);
if(s->mACodecAudioDecoder == NULL)
{
printf("Failed to create mACodecAudioDecoder\n");
return -1;
}
ret = s->mACodecAudioDecoder->configure(
format, NULL /* surface */,
NULL /* crypto */,
0 /* flags */);
if(ret != OK)
{
printf("Failed to configure mACodecAudioDecoder\n");
return -1;
}
printf("[%s]@ACodec::Create____________________________END\n", __FUNCTION__);
ret = s->mACodecAudioDecoder->start();
if(ret != OK)
{
printf("Failed to start mACodecAudioDecoder\n");
return -1;
}
ret = s->mACodecAudioDecoder->getInputBuffers(&s->mAudioInBuffers);
if(ret != OK)
{
printf("Failed to getInputBuffers mACodecAudioDecoder\n");
return -1;
}
ret = s->mACodecAudioDecoder->getOutputBuffers(&s->mAudioOutBuffers);
if(ret != OK)
{
printf("Failed to getOutputBuffers mACodecAudioDecoder\n");
return -1;
}
printf("got %d input and %d output buffers", s->mAudioInBuffers.size(), s->mAudioOutBuffers.size());
fail:
return ret;
#endif
#endif
}
[/mw_shl_code]
[mw_shl_code=c,false]static void* audio_decode_sound_thread(void *arg)
{
status_t err;
StagefrightContext *s = (StagefrightContext*)arg;
MediaBuffer *buffer = NULL;
printf("[%s]Thread id:%d/n", __FUNCTION__, gettid());
if(audio_decoder_init(s, para.audio) == -1)
return NULL;
size_t frameCount = 0;
if (AudioTrack::getMinFrameCount(&frameCount, AUDIO_STREAM_DEFAULT, s->mSampleRate) != NO_ERROR) {
return NULL;
}
int nbChannels = 2;
int audioFormat = ENCODING_PCM_16BIT;
size_t size = frameCount * nbChannels * (audioFormat == ENCODING_PCM_16BIT ? 2 : 1);
printf("size is %d, s->mSampleRate is %d\n", size, s->mSampleRate);
s->mAudioTrack = new AudioTrack(AUDIO_STREAM_MUSIC,
s->mSampleRate,
AUDIO_FORMAT_PCM_16_BIT,
AUDIO_CHANNEL_OUT_STEREO,
0,
AUDIO_OUTPUT_FLAG_NONE,
NULL,
NULL,
0);
if ((err = s->mAudioTrack->initCheck()) != OK) {
printf("AudioTrack initCheck failed\n");
s->mAudioTrack.clear();
}
s->mAudioTrack->setVolume(1.0f);
s->mAudioTrack->start();
#if 1
#if (defined OMXCODEC)
while(1)
{
status_t status = (*s->mAudioDecoder)->read(&buffer, NULL);
if (status == OK) {
printf("%s@AUDIO DECODER OK\n", __FUNCTION__);
if (buffer->range_length() == 0)
{
printf("%s:ERROR_BUFFER_TOO_SMALL\n", __FUNCTION__);
status = ERROR_BUFFER_TOO_SMALL;
buffer->release();
buffer = NULL;
continue;
}
//printf("BUFFER RANGE LENGTH[%d]\n", buffer->range_length());
}
else
;//printf("%s@AUDIO DECODER NOT OK\n", __FUNCTION__);
if(status == OK) {
sp<MetaData> outFormat = (*s->mAudioDecoder)->getFormat();
outFormat->findInt32(kKeySampleRate, &s->mSampleRate);
printf("SAMPLERATE[%d]\n", s->mSampleRate);
}
if (status == OK) {
s->mAudioTrack->write(buffer->data(), buffer->range_length());
buffer->release();
buffer = NULL;
}
}
#elif (defined ACODEC)
static int first_flag = true;
int sampleSize;
static int64_t kTimeout_audio = 10000;
size_t inIndex;
size_t outIndex;
size_t offset;
size_t len;
int64_t presentationTimeUs;
uint32_t flags;
while(1)
{
err = s->mACodecAudioDecoder->dequeueInputBuffer(&inIndex, kTimeout_audio);
if (err == OK) {
//printf("filling input buffer %d\n", inIndex);
const sp<ABuffer> &buffer = s->mAudioInBuffers.itemAt(inIndex);
if((para.audio.stream_type == AUDIO_AAC_ADTS) && first_flag)
{
memcpy((uint8_t *)buffer->data(), para.audio.csd, 2);
sampleSize = 2;
first_flag = false;
}
else
{
sampleSize = audio_read_one_frame((uint8_t *)buffer->data());
}
presentationTimeUs = 0;
if(sampleSize <= 0)
break;
if (buffer->capacity() < sampleSize) {
printf("buffer capacity overflow\n");
break;
}
buffer->setRange(0, sampleSize);
err = s->mACodecAudioDecoder->queueInputBuffer(
inIndex,
0 /* offset */,
buffer->size(),
presentationTimeUs,
0 /* flag*/);
//printf("queueInputBuffer err is %d\n", err);
}
err = s->mACodecAudioDecoder->dequeueOutputBuffer(&outIndex, &offset, &len, &presentationTimeUs, &flags, kTimeout_audio);
//printf("dequeueOutputBuffer err is %d\n", err);
if (err == OK) {
s->mACodecAudioDecoder->getOutputBuffers(&s->mAudioOutBuffers);
//printf("got %d output buffers", s->mAudioOutBuffers.size());
const sp<ABuffer> &buffer = s->mAudioOutBuffers.itemAt(outIndex);
//printf("output buffers[%d] size[%d]\n",outIndex, buffer->size());
s->mAudioTrack->write(buffer->data(), buffer->size());
s->mACodecAudioDecoder->releaseOutputBuffer(outIndex);
}
}
#endif
#endif
}[/mw_shl_code]
|
|