Skip to content

Commit 3e408f3

Browse files
committed
Support AMR, G.711 and vorbis audio in ACodec and friends.
Change-Id: I08c03219bf2d60fc5c6e89957bd4b4c615570983
1 parent 9a3d51e commit 3e408f3

File tree

4 files changed

+147
-8
lines changed

4 files changed

+147
-8
lines changed

cmds/stagefright/sf2.cpp

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ struct Controller : public AHandler {
4646
mDecodeAudio(decodeAudio),
4747
mSurface(surface),
4848
mRenderToSurface(renderToSurface),
49-
mCodec(new ACodec) {
49+
mCodec(new ACodec),
50+
mIsVorbis(false) {
5051
CHECK(!mDecodeAudio || mSurface == NULL);
5152
}
5253

@@ -85,6 +86,12 @@ struct Controller : public AHandler {
8586
if (!strncasecmp(mDecodeAudio ? "audio/" : "video/",
8687
mime, 6)) {
8788
mSource = extractor->getTrack(i);
89+
90+
if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
91+
mIsVorbis = true;
92+
} else {
93+
mIsVorbis = false;
94+
}
8895
break;
8996
}
9097
}
@@ -227,6 +234,7 @@ struct Controller : public AHandler {
227234
bool mRenderToSurface;
228235
sp<ACodec> mCodec;
229236
sp<MediaSource> mSource;
237+
bool mIsVorbis;
230238

231239
Vector<sp<ABuffer> > mCSD;
232240
size_t mCSDIndex;
@@ -367,6 +375,20 @@ struct Controller : public AHandler {
367375
memcpy(buffer->data(), codec_specific_data,
368376
codec_specific_data_size);
369377

378+
buffer->meta()->setInt32("csd", true);
379+
mCSD.push(buffer);
380+
} else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
381+
sp<ABuffer> buffer = new ABuffer(size);
382+
memcpy(buffer->data(), data, size);
383+
384+
buffer->meta()->setInt32("csd", true);
385+
mCSD.push(buffer);
386+
387+
CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
388+
389+
buffer = new ABuffer(size);
390+
memcpy(buffer->data(), data, size);
391+
370392
buffer->meta()->setInt32("csd", true);
371393
mCSD.push(buffer);
372394
}
@@ -423,10 +445,17 @@ struct Controller : public AHandler {
423445
}
424446
}
425447

426-
if (inBuffer->range_length() > sizeLeft) {
448+
size_t sizeNeeded = inBuffer->range_length();
449+
if (mIsVorbis) {
450+
// Vorbis data is suffixed with the number of
451+
// valid samples on the page.
452+
sizeNeeded += sizeof(int32_t);
453+
}
454+
455+
if (sizeNeeded > sizeLeft) {
427456
if (outBuffer->size() == 0) {
428457
LOGE("Unable to fit even a single input buffer of size %d.",
429-
inBuffer->range_length());
458+
sizeNeeded);
430459
}
431460
CHECK_GT(outBuffer->size(), 0u);
432461

@@ -448,10 +477,22 @@ struct Controller : public AHandler {
448477
+ inBuffer->range_offset(),
449478
inBuffer->range_length());
450479

480+
if (mIsVorbis) {
481+
int32_t numPageSamples;
482+
if (!inBuffer->meta_data()->findInt32(
483+
kKeyValidSamples, &numPageSamples)) {
484+
numPageSamples = -1;
485+
}
486+
487+
memcpy(outBuffer->data()
488+
+ outBuffer->size() + inBuffer->range_length(),
489+
&numPageSamples, sizeof(numPageSamples));
490+
}
491+
451492
outBuffer->setRange(
452-
0, outBuffer->size() + inBuffer->range_length());
493+
0, outBuffer->size() + sizeNeeded);
453494

454-
sizeLeft -= inBuffer->range_length();
495+
sizeLeft -= sizeNeeded;
455496

456497
inBuffer->release();
457498
inBuffer = NULL;

include/media/stagefright/ACodec.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ struct ACodec : public AHierarchicalStateMachine {
151151
OMX_VIDEO_CODINGTYPE compressionFormat);
152152

153153
status_t setupAACDecoder(int32_t numChannels, int32_t sampleRate);
154+
status_t setupAMRDecoder(bool isWAMR);
155+
status_t setupG711Decoder(int32_t numChannels);
156+
157+
status_t setupRawAudioFormat(
158+
OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
159+
154160
status_t setMinBufferSize(OMX_U32 portIndex, size_t size);
155161

156162
status_t initNativeWindow();

media/libstagefright/ACodec.cpp

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,8 @@ void ACodec::setComponentRole(
687687
"audio_decoder.amrwb", "audio_encoder.amrwb" },
688688
{ MEDIA_MIMETYPE_AUDIO_AAC,
689689
"audio_decoder.aac", "audio_encoder.aac" },
690+
{ MEDIA_MIMETYPE_AUDIO_VORBIS,
691+
"audio_decoder.vorbis", "audio_encoder.vorbis" },
690692
{ MEDIA_MIMETYPE_VIDEO_AVC,
691693
"video_decoder.avc", "video_encoder.avc" },
692694
{ MEDIA_MIMETYPE_VIDEO_MPEG4,
@@ -750,9 +752,19 @@ void ACodec::configureCodec(
750752
CHECK(msg->findInt32("sample-rate", &sampleRate));
751753

752754
CHECK_EQ(setupAACDecoder(numChannels, sampleRate), (status_t)OK);
753-
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
754-
} else {
755-
TRESPASS();
755+
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
756+
CHECK_EQ(setupAMRDecoder(false /* isWAMR */), (status_t)OK);
757+
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
758+
CHECK_EQ(setupAMRDecoder(true /* isWAMR */), (status_t)OK);
759+
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
760+
|| !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
761+
// These are PCM-like formats with a fixed sample rate but
762+
// a variable number of channels.
763+
764+
int32_t numChannels;
765+
CHECK(msg->findInt32("channel-count", &numChannels));
766+
767+
CHECK_EQ(setupG711Decoder(numChannels), (status_t)OK);
756768
}
757769

758770
int32_t maxInputSize;
@@ -824,6 +836,84 @@ status_t ACodec::setupAACDecoder(int32_t numChannels, int32_t sampleRate) {
824836
return err;
825837
}
826838

839+
status_t ACodec::setupAMRDecoder(bool isWAMR) {
840+
OMX_AUDIO_PARAM_AMRTYPE def;
841+
InitOMXParams(&def);
842+
def.nPortIndex = kPortIndexInput;
843+
844+
status_t err =
845+
mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
846+
847+
if (err != OK) {
848+
return err;
849+
}
850+
851+
def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
852+
853+
def.eAMRBandMode =
854+
isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0;
855+
856+
return mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
857+
}
858+
859+
status_t ACodec::setupG711Decoder(int32_t numChannels) {
860+
return setupRawAudioFormat(
861+
kPortIndexInput, 8000 /* sampleRate */, numChannels);
862+
}
863+
864+
status_t ACodec::setupRawAudioFormat(
865+
OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
866+
OMX_PARAM_PORTDEFINITIONTYPE def;
867+
InitOMXParams(&def);
868+
def.nPortIndex = portIndex;
869+
870+
status_t err = mOMX->getParameter(
871+
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
872+
873+
if (err != OK) {
874+
return err;
875+
}
876+
877+
def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
878+
879+
err = mOMX->setParameter(
880+
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
881+
882+
if (err != OK) {
883+
return err;
884+
}
885+
886+
OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
887+
InitOMXParams(&pcmParams);
888+
pcmParams.nPortIndex = portIndex;
889+
890+
err = mOMX->getParameter(
891+
mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
892+
893+
if (err != OK) {
894+
return err;
895+
}
896+
897+
pcmParams.nChannels = numChannels;
898+
pcmParams.eNumData = OMX_NumericalDataSigned;
899+
pcmParams.bInterleaved = OMX_TRUE;
900+
pcmParams.nBitPerSample = 16;
901+
pcmParams.nSamplingRate = sampleRate;
902+
pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
903+
904+
if (numChannels == 1) {
905+
pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
906+
} else {
907+
CHECK_EQ(numChannels, 2);
908+
909+
pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
910+
pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
911+
}
912+
913+
return mOMX->setParameter(
914+
mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
915+
}
916+
827917
status_t ACodec::setVideoPortFormatType(
828918
OMX_U32 portIndex,
829919
OMX_VIDEO_CODINGTYPE compressionFormat,

media/libstagefright/OMXCodec.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,8 @@ void OMXCodec::setComponentRole(
14851485
"audio_decoder.amrwb", "audio_encoder.amrwb" },
14861486
{ MEDIA_MIMETYPE_AUDIO_AAC,
14871487
"audio_decoder.aac", "audio_encoder.aac" },
1488+
{ MEDIA_MIMETYPE_AUDIO_VORBIS,
1489+
"audio_decoder.vorbis", "audio_encoder.vorbis" },
14881490
{ MEDIA_MIMETYPE_VIDEO_AVC,
14891491
"video_decoder.avc", "video_encoder.avc" },
14901492
{ MEDIA_MIMETYPE_VIDEO_MPEG4,

0 commit comments

Comments
 (0)