From fb1c2f8d8d8a7ae9cd1f5288f8845485f72a9a91 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Tue, 15 Dec 2009 13:25:11 -0800 Subject: [PATCH] Properly integrate the software codecs into the OMXCodec::Create hierarchy of available components. --- media/libstagefright/OMXCodec.cpp | 103 ++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 21 deletions(-) diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 5a89b738f18bd..99c39f8a7caa0 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -55,15 +55,68 @@ struct CodecInfo { const char *codec; }; +#if BUILD_WITH_FULL_STAGEFRIGHT +#define OPTIONAL(x,y) { x, y }, + +#define FACTORY_CREATE(name) \ +static sp Make##name(const sp &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 InstantiateSoftwareCodec( + const char *name, const sp &source) { + struct FactoryInfo { + const char *name; + sp (*CreateFunc)(const sp &); + }; + + 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 @@ static const CodecInfo kDecoderInfo[] = { { 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 @@ static const CodecInfo kEncoderInfo[] = { { 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 @@ static bool IsSoftwareCodec(const char *componentName) { 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 @@ sp OMXCodec::Create( 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 matchingCodecs; findMatchingCodecs( mime, createEncoder, matchComponentName, flags, &matchingCodecs); @@ -330,6 +380,17 @@ sp OMXCodec::Create( for (size_t i = 0; i < matchingCodecs.size(); ++i) { componentName = matchingCodecs[i].string(); +#if BUILD_WITH_FULL_STAGEFRIGHT + sp 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);