diff --git a/media/omx-plugin/OmxPlugin.cpp b/media/omx-plugin/OmxPlugin.cpp index 185bdfa9011..981edf00f3d 100644 --- a/media/omx-plugin/OmxPlugin.cpp +++ b/media/omx-plugin/OmxPlugin.cpp @@ -242,7 +242,7 @@ static sp GetOMX() { } #endif -static uint32_t GetVideoCreationFlags(PluginHost* pluginHost) +static uint32_t GetVideoCreationFlags(PluginHost* aPluginHost) { #ifdef MOZ_WIDGET_GONK // Flag value of zero means return a hardware or software decoder @@ -256,7 +256,7 @@ static uint32_t GetVideoCreationFlags(PluginHost* pluginHost) // 8 = Force software decoding // 16 = Force hardware decoding int32_t flags = 0; - pluginHost->GetIntPref("media.stagefright.omxcodec.flags", &flags); + aPluginHost->GetIntPref("media.stagefright.omxcodec.flags", &flags); if (flags != 0) { LOG("media.stagefright.omxcodec.flags=%d", flags); if ((flags & OMXCodec::kHardwareCodecsOnly) != 0) { @@ -269,6 +269,55 @@ static uint32_t GetVideoCreationFlags(PluginHost* pluginHost) #endif } +static sp CreateVideoSource(PluginHost* aPluginHost, + const sp& aOmx, + const sp& aVideoTrack) +{ + uint32_t flags = GetVideoCreationFlags(aPluginHost); + if (flags == 0) { + // Let Stagefright choose hardware or software decoder. + sp videoSource = OMXCodec::Create(aOmx, aVideoTrack->getFormat(), + false, aVideoTrack, NULL, 0); + if (videoSource == NULL) + return NULL; + + // Now that OMXCodec has parsed the video's AVCDecoderConfigurationRecord, + // check whether we know how to decode this video. + int32_t videoColorFormat; + if (videoSource->getFormat()->findInt32(kKeyColorFormat, &videoColorFormat)) { + switch (videoColorFormat) { + // We know how to convert these color formats. + case OMX_COLOR_FormatCbYCrY: + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_QCOM_COLOR_FormatYVU420PackedSemiPlanar32m4ka: + case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: + case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: + // Use the decoder Stagefright chose for us! + return videoSource; + + // Use software decoder for color formats we don't know how to convert. + default: + // We need to implement a ToVideoFrame_*() color conversion + // function for this video color format. + LOG("Unknown video color format: %#x", videoColorFormat); + break; + } + } else { + LOG("Video color format not found"); + } + + // Throw away the videoSource and try again with new flags. + LOG("Falling back to software decoder"); + videoSource.clear(); + flags = OMXCodec::kSoftwareCodecsOnly; + } + + MOZ_ASSERT(flags != 0); + return OMXCodec::Create(aOmx, aVideoTrack->getFormat(), false, aVideoTrack, + NULL, flags); +} + bool OmxDecoder::Init() { //register sniffers, if they are not registered in this process. DataSource::RegisterDefaultSniffers(); @@ -330,13 +379,7 @@ bool OmxDecoder::Init() { sp videoTrack; sp videoSource; if (videoTrackIndex != -1 && (videoTrack = extractor->getTrack(videoTrackIndex)) != NULL) { - uint32_t flags = GetVideoCreationFlags(mPluginHost); - videoSource = OMXCodec::Create(omx, - videoTrack->getFormat(), - false, // decoder - videoTrack, - NULL, - flags); + videoSource = CreateVideoSource(mPluginHost, omx, videoTrack); if (videoSource == NULL) { LOG("OMXCodec failed to initialize video decoder for \"%s\"", videoMime); return false;