Bug 1174977 - Disable browser_private_search_perwindowpb.js on the hopes that'll it'll stop the Win8 PB permafailing. a=me
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* vim:set ts=2 sw=2 sts=2 et cindent: *//* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */#include"GStreamerFormatHelper.h"#include"nsCharSeparatedTokenizer.h"#include"nsString.h"#include"GStreamerLoader.h"#include"mozilla/Logging.h"#include"mozilla/Preferences.h"#define ENTRY_FORMAT(entry) entry[0]#define ENTRY_CAPS(entry) entry[1]namespacemozilla{externPRLogModuleInfo*gMediaDecoderLog;#define LOG(msg, ...) \ MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, ("GStreamerFormatHelper " msg, ##__VA_ARGS__))GStreamerFormatHelper*GStreamerFormatHelper::gInstance=nullptr;boolGStreamerFormatHelper::sLoadOK=false;GStreamerFormatHelper*GStreamerFormatHelper::Instance(){if(!gInstance){if((sLoadOK=load_gstreamer())){gst_init(nullptr,nullptr);}gInstance=newGStreamerFormatHelper();}returngInstance;}voidGStreamerFormatHelper::Shutdown(){deletegInstance;gInstance=nullptr;}staticcharconst*constsContainers[6][2]={{"video/mp4","video/quicktime"},{"video/quicktime","video/quicktime"},{"audio/mp4","audio/x-m4a"},{"audio/x-m4a","audio/x-m4a"},{"audio/mpeg","audio/mpeg, mpegversion=(int)1"},{"audio/mp3","audio/mpeg, mpegversion=(int)1"},};staticcharconst*constsCodecs[9][2]={{"avc1.42E01E","video/x-h264"},{"avc1.42001E","video/x-h264"},{"avc1.58A01E","video/x-h264"},{"avc1.4D401E","video/x-h264"},{"avc1.64001E","video/x-h264"},{"avc1.64001F","video/x-h264"},{"mp4v.20.3","video/3gpp"},{"mp4a.40.2","audio/mpeg, mpegversion=(int)4"},{"mp3","audio/mpeg, mpegversion=(int)1"},};staticcharconst*constsDefaultCodecCaps[][2]={{"video/mp4","video/x-h264"},{"video/quicktime","video/x-h264"},{"audio/mp4","audio/mpeg, mpegversion=(int)4"},{"audio/x-m4a","audio/mpeg, mpegversion=(int)4"},{"audio/mp3","audio/mpeg, layer=(int)3"},{"audio/mpeg","audio/mpeg, layer=(int)3"}};staticcharconst*constsPluginBlacklist[]={"flump3dec","h264parse",};GStreamerFormatHelper::GStreamerFormatHelper():mFactories(nullptr),mCookie(static_cast<uint32_t>(-1)){if(!sLoadOK){return;}mSupportedContainerCaps=gst_caps_new_empty();for(unsignedinti=0;i<G_N_ELEMENTS(sContainers);i++){constchar*capsString=sContainers[i][1];GstCaps*caps=gst_caps_from_string(capsString);gst_caps_append(mSupportedContainerCaps,caps);}mSupportedCodecCaps=gst_caps_new_empty();for(unsignedinti=0;i<G_N_ELEMENTS(sCodecs);i++){constchar*capsString=sCodecs[i][1];GstCaps*caps=gst_caps_from_string(capsString);gst_caps_append(mSupportedCodecCaps,caps);}}GStreamerFormatHelper::~GStreamerFormatHelper(){if(!sLoadOK){return;}gst_caps_unref(mSupportedContainerCaps);gst_caps_unref(mSupportedCodecCaps);if(mFactories)g_list_free(mFactories);}staticGstCaps*GetContainerCapsFromMIMEType(constchar*aType){/* convert aMIMEType to gst container caps */constchar*capsString=nullptr;for(uint32_ti=0;i<G_N_ELEMENTS(sContainers);i++){if(!strcmp(ENTRY_FORMAT(sContainers[i]),aType)){capsString=ENTRY_CAPS(sContainers[i]);break;}}if(!capsString){/* we couldn't find any matching caps */returnnullptr;}returngst_caps_from_string(capsString);}staticGstCaps*GetDefaultCapsFromMIMEType(constchar*aType){GstCaps*caps=GetContainerCapsFromMIMEType(aType);for(uint32_ti=0;i<G_N_ELEMENTS(sDefaultCodecCaps);i++){if(!strcmp(sDefaultCodecCaps[i][0],aType)){GstCaps*tmp=gst_caps_from_string(sDefaultCodecCaps[i][1]);gst_caps_append(caps,tmp);returncaps;}}returnnullptr;}boolGStreamerFormatHelper::CanHandleMediaType(constnsACString&aMIMEType,constnsAString*aCodecs){if(!sLoadOK){returnfalse;}constchar*type;NS_CStringGetData(aMIMEType,&type,nullptr);GstCaps*caps;if(aCodecs&&!aCodecs->IsEmpty()){caps=ConvertFormatsToCaps(type,aCodecs);}else{// Get a minimal set of codec caps for this MIME type we should support so// that we don't overreport MIME types we are able to play.caps=GetDefaultCapsFromMIMEType(type);}if(!caps){returnfalse;}boolret=HaveElementsToProcessCaps(caps);gst_caps_unref(caps);returnret;}GstCaps*GStreamerFormatHelper::ConvertFormatsToCaps(constchar*aMIMEType,constnsAString*aCodecs){NS_ASSERTION(sLoadOK,"GStreamer library not linked");unsignedinti;GstCaps*caps=GetContainerCapsFromMIMEType(aMIMEType);if(!caps){returnnullptr;}/* container only */if(!aCodecs){returncaps;}nsCharSeparatedTokenizertokenizer(*aCodecs,',');while(tokenizer.hasMoreTokens()){constnsSubstring&codec=tokenizer.nextToken();constchar*capsString=nullptr;for(i=0;i<G_N_ELEMENTS(sCodecs);i++){if(codec.EqualsASCII(ENTRY_FORMAT(sCodecs[i]))){capsString=ENTRY_CAPS(sCodecs[i]);break;}}if(!capsString){gst_caps_unref(caps);returnnullptr;}GstCaps*tmp=gst_caps_from_string(capsString);/* appends and frees tmp */gst_caps_append(caps,tmp);}returncaps;}/* static */boolGStreamerFormatHelper::IsBlacklistEnabled(){staticboolsBlacklistEnabled;staticboolsBlacklistEnabledCached=false;if(!sBlacklistEnabledCached){Preferences::AddBoolVarCache(&sBlacklistEnabled,"media.gstreamer.enable-blacklist",true);sBlacklistEnabledCached=true;}returnsBlacklistEnabled;}/* static */boolGStreamerFormatHelper::IsPluginFeatureBlacklisted(GstPluginFeature*aFeature){if(!IsBlacklistEnabled()){returnfalse;}constgchar*factoryName=gst_plugin_feature_get_name(aFeature);for(unsignedinti=0;i<G_N_ELEMENTS(sPluginBlacklist);i++){if(!strcmp(factoryName,sPluginBlacklist[i])){LOG("rejecting disabled plugin %s",factoryName);returntrue;}}returnfalse;}staticgbooleanFactoryFilter(GstPluginFeature*aFeature,gpointer){if(!GST_IS_ELEMENT_FACTORY(aFeature)){returnFALSE;}constgchar*className=gst_element_factory_get_klass(GST_ELEMENT_FACTORY_CAST(aFeature));if(!strstr(className,"Decoder")&&!strstr(className,"Demux")&&!strstr(className,"Parser")){returnFALSE;}returngst_plugin_feature_get_rank(aFeature)>=GST_RANK_MARGINAL&&!GStreamerFormatHelper::IsPluginFeatureBlacklisted(aFeature);}/** * Returns true if any |aFactory| caps intersect with |aCaps| */staticboolSupportsCaps(GstElementFactory*aFactory,GstCaps*aCaps){for(constGList*iter=gst_element_factory_get_static_pad_templates(aFactory);iter;iter=iter->next){GstStaticPadTemplate*templ=static_cast<GstStaticPadTemplate*>(iter->data);if(templ->direction==GST_PAD_SRC){continue;}GstCaps*caps=gst_static_caps_get(&templ->static_caps);if(!caps){continue;}boolsupported=gst_caps_can_intersect(caps,aCaps);gst_caps_unref(caps);if(supported){returntrue;}}returnfalse;}boolGStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps*aCaps){NS_ASSERTION(sLoadOK,"GStreamer library not linked");GList*factories=GetFactories();/* here aCaps contains [containerCaps, [codecCaps1, [codecCaps2, ...]]] so process * caps structures individually as we want one element for _each_ * structure */for(unsignedinti=0;i<gst_caps_get_size(aCaps);i++){GstStructure*s=gst_caps_get_structure(aCaps,i);GstCaps*caps=gst_caps_new_full(gst_structure_copy(s),nullptr);boolfound=false;for(GList*elem=factories;elem;elem=elem->next){if(SupportsCaps(GST_ELEMENT_FACTORY_CAST(elem->data),caps)){found=true;break;}}gst_caps_unref(caps);if(!found){returnfalse;}}returntrue;}boolGStreamerFormatHelper::CanHandleContainerCaps(GstCaps*aCaps){NS_ASSERTION(sLoadOK,"GStreamer library not linked");returngst_caps_can_intersect(aCaps,mSupportedContainerCaps);}boolGStreamerFormatHelper::CanHandleCodecCaps(GstCaps*aCaps){NS_ASSERTION(sLoadOK,"GStreamer library not linked");returngst_caps_can_intersect(aCaps,mSupportedCodecCaps);}GList*GStreamerFormatHelper::GetFactories(){NS_ASSERTION(sLoadOK,"GStreamer library not linked");#if GST_VERSION_MAJOR >= 1uint32_tcookie=gst_registry_get_feature_list_cookie(gst_registry_get());#elseuint32_tcookie=gst_default_registry_get_feature_list_cookie();#endifif(cookie!=mCookie){g_list_free(mFactories);#if GST_VERSION_MAJOR >= 1mFactories=gst_registry_feature_filter(gst_registry_get(),(GstPluginFeatureFilter)FactoryFilter,false,nullptr);#elsemFactories=gst_default_registry_feature_filter((GstPluginFeatureFilter)FactoryFilter,false,nullptr);#endifmCookie=cookie;}returnmFactories;}}// namespace mozilla