From 932b02e1514ef15c6b7c71814b38b0ddae182b3b Mon Sep 17 00:00:00 2001 From: Edwin Flores Date: Thu, 30 Jan 2014 13:26:54 -0500 Subject: [PATCH] Bug 963621 - Stop passing kClientNeedsFramebuffer into Qualcomm OMXCodec. r=doublec Qualcomm's OMXCodec implementation interprets the kClientNeedsFramebuffer flag to mean that we only want a thumbnail. Thus, it returns only one frame and then returns EOS. This patch adds a Qualcomm-specific hack to not pass their decoder this flag. --- content/media/plugins/MPAPI.h | 1 + content/media/plugins/MediaPluginHost.cpp | 24 +++++++++++++++- media/omx-plugin/OmxPlugin.cpp | 34 ++++++++++++++++++----- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/content/media/plugins/MPAPI.h b/content/media/plugins/MPAPI.h index 4ebe642989b..8394e8ff587 100644 --- a/content/media/plugins/MPAPI.h +++ b/content/media/plugins/MPAPI.h @@ -135,6 +135,7 @@ struct PluginHost { void (*SetMetaDataReadMode)(Decoder *aDecoder); void (*SetPlaybackReadMode)(Decoder *aDecoder); bool (*GetIntPref)(const char *aPref, int32_t *aResult); + bool (*GetSystemInfoString)(const char *aKey, char *aResult, uint32_t aResultLen); }; struct Decoder { diff --git a/content/media/plugins/MediaPluginHost.cpp b/content/media/plugins/MediaPluginHost.cpp index 93d58b9268d..58b4ee61eee 100644 --- a/content/media/plugins/MediaPluginHost.cpp +++ b/content/media/plugins/MediaPluginHost.cpp @@ -67,12 +67,34 @@ static bool GetIntPref(const char* aPref, int32_t* aResult) return NS_SUCCEEDED(NS_DispatchToMainThread(event, NS_DISPATCH_SYNC)); } +static bool +GetSystemInfoString(const char *aKey, char *aResult, size_t aResultLength) +{ + NS_ENSURE_TRUE(aKey, false); + NS_ENSURE_TRUE(aResult, false); + + nsCOMPtr infoService = do_GetService("@mozilla.org/system-info;1"); + NS_ASSERTION(infoService, "Could not find a system info service"); + + nsAutoCString key(aKey); + nsAutoCString info; + nsresult rv = infoService->GetPropertyAsACString(NS_ConvertUTF8toUTF16(key), + info); + + NS_ENSURE_SUCCESS(rv, false); + + strncpy(aResult, info.get(), aResultLength); + + return true; +} + static PluginHost sPluginHost = { nullptr, nullptr, nullptr, nullptr, - GetIntPref + GetIntPref, + GetSystemInfoString, }; // Return true if Omx decoding is supported on the device. This checks the diff --git a/media/omx-plugin/OmxPlugin.cpp b/media/omx-plugin/OmxPlugin.cpp index 0a907521b8c..158d30fcd45 100644 --- a/media/omx-plugin/OmxPlugin.cpp +++ b/media/omx-plugin/OmxPlugin.cpp @@ -26,12 +26,6 @@ #define MAX_DECODER_NAME_LEN 256 #define AVC_MIME_TYPE "video/avc" -#if !defined(MOZ_ANDROID_FROYO) -#define DEFAULT_STAGEFRIGHT_FLAGS OMXCodec::kClientNeedsFramebuffer -#else -#define DEFAULT_STAGEFRIGHT_FLAGS 0 -#endif - #undef LOG #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "OmxPlugin" , ## args) @@ -210,6 +204,32 @@ static sp GetOMX() { } #endif +static uint32_t +GetDefaultStagefrightFlags(PluginHost *aPluginHost) +{ + uint32_t flags = 0; + +#if !defined(MOZ_ANDROID_FROYO) + + char hardware[256]; + aPluginHost->GetSystemInfoString("hardware", hardware, sizeof(hardware)); + + if (hardware && strcmp("qcom", hardware)) { + // Qualcomm's OMXCodec implementation interprets this flag to mean that we + // only want a thumbnail and therefore only need one frame. After the first + // frame it returns EOS. + // All other OMXCodec implementations seen so far interpret this flag + // sanely; some do not return full framebuffers unless this flag is passed. + flags |= OMXCodec::kClientNeedsFramebuffer; + } + + LOG("Hardware %s; using default flags %#x\n", hardware, flags); + +#endif + + return flags; +} + static uint32_t GetVideoCreationFlags(PluginHost* aPluginHost) { #ifdef MOZ_WIDGET_GONK @@ -236,7 +256,7 @@ static uint32_t GetVideoCreationFlags(PluginHost* aPluginHost) #endif } - flags |= DEFAULT_STAGEFRIGHT_FLAGS; + flags |= GetDefaultStagefrightFlags(aPluginHost); return static_cast(flags); #endif