From 228ef9f9f74bf4eb9f6663bf82ce537de0344ada Mon Sep 17 00:00:00 2001 From: Edwin Flores Date: Tue, 28 Jan 2014 17:31:00 +1300 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 | 28 ++++++++++++++++++++++- 3 files changed, 51 insertions(+), 2 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..81cf3d3d946 100644 --- a/media/omx-plugin/OmxPlugin.cpp +++ b/media/omx-plugin/OmxPlugin.cpp @@ -210,6 +210,32 @@ static sp GetOMX() { } #endif +static uint32_t +GetDefaultStagefrightFlags(PluginHost *aPluginHost) +{ + uint32_t flags = DEFAULT_STAGEFRIGHT_FLAGS; + +#if !defined(MOZ_ANDROID_FROYO) + + char hardware[256] = ""; + aPluginHost->GetSystemInfoString("hardware", hardware, sizeof(hardware)); + + if (!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 +262,7 @@ static uint32_t GetVideoCreationFlags(PluginHost* aPluginHost) #endif } - flags |= DEFAULT_STAGEFRIGHT_FLAGS; + flags |= GetDefaultStagefrightFlags(aPluginHost); return static_cast(flags); #endif