Merge change I7f11a67a into eclair-mr2
* changes:
Properly integrate the software codecs into the OMXCodec::Create hierarchy of available components.
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 5a89b73..99c39f8 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -55,15 +55,68 @@
const char *codec;
};
+#if BUILD_WITH_FULL_STAGEFRIGHT
+#define OPTIONAL(x,y) { x, y },
+
+#define FACTORY_CREATE(name) \
+static sp<MediaSource> Make##name(const sp<MediaSource> &source) { \
+ return new name(source); \
+}
+
+#define FACTORY_REF(name) { #name, Make##name },
+
+FACTORY_CREATE(MP3Decoder)
+FACTORY_CREATE(AMRNBDecoder)
+FACTORY_CREATE(AMRWBDecoder)
+FACTORY_CREATE(AACDecoder)
+FACTORY_CREATE(AVCDecoder)
+FACTORY_CREATE(AMRNBEncoder)
+
+static sp<MediaSource> InstantiateSoftwareCodec(
+ const char *name, const sp<MediaSource> &source) {
+ struct FactoryInfo {
+ const char *name;
+ sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &);
+ };
+
+ static const FactoryInfo kFactoryInfo[] = {
+ FACTORY_REF(MP3Decoder)
+ FACTORY_REF(AMRNBDecoder)
+ FACTORY_REF(AMRWBDecoder)
+ FACTORY_REF(AACDecoder)
+ FACTORY_REF(AVCDecoder)
+ FACTORY_REF(AMRNBEncoder)
+ };
+ for (size_t i = 0;
+ i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) {
+ if (!strcmp(name, kFactoryInfo[i].name)) {
+ return (*kFactoryInfo[i].CreateFunc)(source);
+ }
+ }
+
+ return NULL;
+}
+
+#undef FACTORY_REF
+#undef FACTORY_CREATE
+
+#else
+#define OPTIONAL(x,y)
+#endif
+
static const CodecInfo kDecoderInfo[] = {
{ MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
{ MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
+ OPTIONAL(MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder")
{ MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
+ OPTIONAL(MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder")
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
+ OPTIONAL(MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder")
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
+ OPTIONAL(MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder")
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
@@ -73,11 +126,13 @@
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
+ OPTIONAL(MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder")
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
};
static const CodecInfo kEncoderInfo[] = {
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
+ OPTIONAL(MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder")
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrencnb" },
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
@@ -92,6 +147,8 @@
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
};
+#undef OPTIONAL
+
#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
@@ -188,8 +245,22 @@
return false;
}
+// A sort order in which non-OMX components are first,
+// followed by software codecs, i.e. OMX.PV.*, followed
+// by all the others.
static int CompareSoftwareCodecsFirst(
const String8 *elem1, const String8 *elem2) {
+ bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4);
+ bool isNotOMX2 = strncmp(elem2->string(), "OMX.", 4);
+
+ if (isNotOMX1) {
+ if (isNotOMX2) { return 0; }
+ return -1;
+ }
+ if (isNotOMX2) {
+ return 1;
+ }
+
bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
@@ -293,27 +364,6 @@
bool success = meta->findCString(kKeyMIMEType, &mime);
CHECK(success);
-#if BUILD_WITH_FULL_STAGEFRIGHT
- if (!createEncoder) {
- if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
- return new AACDecoder(source);
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
- return new AMRNBDecoder(source);
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
- return new AMRWBDecoder(source);
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
- return new MP3Decoder(source);
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
- && (flags & kPreferSoftwareCodecs)) {
- return new AVCDecoder(source);
- }
- } else {
- if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
- return new AMRNBEncoder(source);
- }
- }
-#endif
-
Vector<String8> matchingCodecs;
findMatchingCodecs(
mime, createEncoder, matchComponentName, flags, &matchingCodecs);
@@ -330,6 +380,17 @@
for (size_t i = 0; i < matchingCodecs.size(); ++i) {
componentName = matchingCodecs[i].string();
+#if BUILD_WITH_FULL_STAGEFRIGHT
+ sp<MediaSource> softwareCodec =
+ InstantiateSoftwareCodec(componentName, source);
+
+ if (softwareCodec != NULL) {
+ LOGV("Successfully allocated software codec '%s'", componentName);
+
+ return softwareCodec;
+ }
+#endif
+
LOGV("Attempting to allocate OMX node '%s'", componentName);
status_t err = omx->allocateNode(componentName, observer, &node);