Merge change 24450 into eclair
* changes:
Minor API change in MPEG4Writer, support for amr output into MPEG4 containers.
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 894d46c..433fb18 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -124,6 +124,9 @@
case FOURCC('s', 'a', 'm', 'r'):
return "audio/3gpp";
+ case FOURCC('s', 'a', 'w', 'b'):
+ return "audio/amr-wb";
+
case FOURCC('m', 'p', '4', 'v'):
return "video/mp4v-es";
@@ -189,6 +192,10 @@
--index;
}
+ if (track == NULL) {
+ return NULL;
+ }
+
return track->meta;
}
@@ -472,6 +479,7 @@
case FOURCC('m', 'p', '4', 'a'):
case FOURCC('s', 'a', 'm', 'r'):
+ case FOURCC('s', 'a', 'w', 'b'):
{
if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) {
return ERROR_MALFORMED;
@@ -491,7 +499,8 @@
uint16_t data_ref_index = U16_AT(&buffer[6]);
uint16_t num_channels = U16_AT(&buffer[16]);
- if (!strcasecmp("audio/3gpp", FourCC2MIME(chunk_type))) {
+ if (!strcasecmp("audio/3gpp", FourCC2MIME(chunk_type))
+ || !strcasecmp("audio/amr-wb", FourCC2MIME(chunk_type))) {
// AMR audio is always mono.
num_channels = 1;
}
@@ -705,6 +714,10 @@
--index;
}
+ if (track == NULL) {
+ return NULL;
+ }
+
return new MPEG4Source(
track->meta, mDataSource, track->sampleTable);
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 2e02697..3ab44b0 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2067,6 +2067,55 @@
}
}
+static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) {
+ static const char *kNames[] = {
+ "OMX_AUDIO_AMRBandModeUnused",
+ "OMX_AUDIO_AMRBandModeNB0",
+ "OMX_AUDIO_AMRBandModeNB1",
+ "OMX_AUDIO_AMRBandModeNB2",
+ "OMX_AUDIO_AMRBandModeNB3",
+ "OMX_AUDIO_AMRBandModeNB4",
+ "OMX_AUDIO_AMRBandModeNB5",
+ "OMX_AUDIO_AMRBandModeNB6",
+ "OMX_AUDIO_AMRBandModeNB7",
+ "OMX_AUDIO_AMRBandModeWB0",
+ "OMX_AUDIO_AMRBandModeWB1",
+ "OMX_AUDIO_AMRBandModeWB2",
+ "OMX_AUDIO_AMRBandModeWB3",
+ "OMX_AUDIO_AMRBandModeWB4",
+ "OMX_AUDIO_AMRBandModeWB5",
+ "OMX_AUDIO_AMRBandModeWB6",
+ "OMX_AUDIO_AMRBandModeWB7",
+ "OMX_AUDIO_AMRBandModeWB8",
+ };
+
+ size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
+
+ if (type < 0 || (size_t)type >= numNames) {
+ return "UNKNOWN";
+ } else {
+ return kNames[type];
+ }
+}
+
+static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) {
+ static const char *kNames[] = {
+ "OMX_AUDIO_AMRFrameFormatConformance",
+ "OMX_AUDIO_AMRFrameFormatIF1",
+ "OMX_AUDIO_AMRFrameFormatIF2",
+ "OMX_AUDIO_AMRFrameFormatFSF",
+ "OMX_AUDIO_AMRFrameFormatRTPPayload",
+ "OMX_AUDIO_AMRFrameFormatITU",
+ };
+
+ size_t numNames = sizeof(kNames) / sizeof(kNames[0]);
+
+ if (type < 0 || (size_t)type >= numNames) {
+ return "UNKNOWN";
+ } else {
+ return kNames[type];
+ }
+}
void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
OMX_PARAM_PORTDEFINITIONTYPE def;
@@ -2153,6 +2202,20 @@
? "signed" : "unsigned");
printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode));
+ } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {
+ OMX_AUDIO_PARAM_AMRTYPE amr;
+ InitOMXParams(&amr);
+ amr.nPortIndex = portIndex;
+
+ err = mOMX->get_parameter(
+ mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
+ CHECK_EQ(err, OK);
+
+ printf(" nChannels = %ld\n", amr.nChannels);
+ printf(" eAMRBandMode = %s\n",
+ amrBandModeString(amr.eAMRBandMode));
+ printf(" eAMRFrameFormat = %s\n",
+ amrFrameFormatString(amr.eAMRFrameFormat));
}
break;
@@ -2229,7 +2292,28 @@
// The codec-reported sampleRate is not reliable...
mOutputFormat->setInt32(kKeySampleRate, sampleRate);
} else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
- mOutputFormat->setCString(kKeyMIMEType, "audio/3gpp");
+ OMX_AUDIO_PARAM_AMRTYPE amr;
+ InitOMXParams(&amr);
+ amr.nPortIndex = kPortIndexOutput;
+
+ err = mOMX->get_parameter(
+ mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
+ CHECK_EQ(err, OK);
+
+ CHECK_EQ(amr.nChannels, 1);
+ mOutputFormat->setInt32(kKeyChannelCount, 1);
+
+ if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
+ && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
+ mOutputFormat->setCString(kKeyMIMEType, "audio/3gpp");
+ mOutputFormat->setInt32(kKeySampleRate, 8000);
+ } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
+ && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
+ mOutputFormat->setCString(kKeyMIMEType, "audio/amr-wb");
+ mOutputFormat->setInt32(kKeySampleRate, 16000);
+ } else {
+ CHECK(!"Unknown AMR band mode.");
+ }
} else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
mOutputFormat->setCString(kKeyMIMEType, "audio/mp4a-latm");
} else {