зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to m-i
This commit is contained in:
Коммит
72dfd3bd3f
|
@ -34,7 +34,10 @@ USE_LIBS += [
|
|||
]
|
||||
|
||||
if CONFIG['LIBFUZZER']:
|
||||
USE_LIBS += [ 'fuzzer' ]
|
||||
USE_LIBS += [ 'fuzzer' ]
|
||||
LOCAL_INCLUDES += [
|
||||
'/tools/fuzzing/libfuzzer',
|
||||
]
|
||||
|
||||
if CONFIG['_MSC_VER']:
|
||||
# Always enter a Windows program through wmain, whether or not we're
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/WindowsDllBlocklist.h"
|
||||
|
||||
#ifdef LIBFUZZER
|
||||
#include "FuzzerDefs.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_LINUX_32_SSE2_STARTUP_ERROR
|
||||
#include <cpuid.h>
|
||||
#include "mozilla/Unused.h"
|
||||
|
@ -163,17 +167,6 @@ static bool IsArg(const char* arg, const char* s)
|
|||
|
||||
Bootstrap::UniquePtr gBootstrap;
|
||||
|
||||
#ifdef LIBFUZZER
|
||||
int libfuzzer_main(int argc, char **argv);
|
||||
|
||||
/* This wrapper is used by the libFuzzer main to call into libxul */
|
||||
|
||||
void libFuzzerGetFuncs(const char* moduleName, LibFuzzerInitFunc* initFunc,
|
||||
LibFuzzerTestingFunc* testingFunc) {
|
||||
return gBootstrap->XRE_LibFuzzerGetFuncs(moduleName, initFunc, testingFunc);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int do_main(int argc, char* argv[], char* envp[])
|
||||
{
|
||||
// Allow firefox.exe to launch XULRunner apps via -app <application.ini>
|
||||
|
@ -235,7 +228,7 @@ static int do_main(int argc, char* argv[], char* envp[])
|
|||
|
||||
#ifdef LIBFUZZER
|
||||
if (getenv("LIBFUZZER"))
|
||||
gBootstrap->XRE_LibFuzzerSetMain(argc, argv, libfuzzer_main);
|
||||
gBootstrap->XRE_LibFuzzerSetDriver(fuzzer::FuzzerDriver);
|
||||
#endif
|
||||
|
||||
return gBootstrap->XRE_main(argc, argv, config);
|
||||
|
|
|
@ -855,10 +855,18 @@ pref("places.frecency.embedVisitBonus", 0);
|
|||
pref("places.frecency.framedLinkVisitBonus", 0);
|
||||
pref("places.frecency.linkVisitBonus", 100);
|
||||
pref("places.frecency.typedVisitBonus", 2000);
|
||||
// The bookmarks bonus is always added on top of any other bonus, including
|
||||
// the redirect source and the typed ones.
|
||||
pref("places.frecency.bookmarkVisitBonus", 75);
|
||||
// The redirect source bonus overwrites any transition bonus.
|
||||
// 0 would hide these pages, instead we want them low ranked. Thus we use
|
||||
// linkVisitBonus - bookmarkVisitBonus, so that a bookmarked source is in par
|
||||
// with a common link.
|
||||
pref("places.frecency.redirectSourceVisitBonus", 25);
|
||||
pref("places.frecency.downloadVisitBonus", 0);
|
||||
pref("places.frecency.permRedirectVisitBonus", 0);
|
||||
pref("places.frecency.tempRedirectVisitBonus", 0);
|
||||
// The perm/temp redirects here relate to redirect targets, not sources.
|
||||
pref("places.frecency.permRedirectVisitBonus", 50);
|
||||
pref("places.frecency.tempRedirectVisitBonus", 40);
|
||||
pref("places.frecency.reloadVisitBonus", 0);
|
||||
pref("places.frecency.defaultVisitBonus", 0);
|
||||
|
||||
|
@ -1574,4 +1582,4 @@ pref("browser.formautofill.experimental", false);
|
|||
#ifdef NIGHTLY_BUILD
|
||||
pref("urlclassifier.malwareTable", "goog-malware-shavar,goog-unwanted-shavar,goog-malware-proto,goog-unwanted-proto,test-malware-simple,test-unwanted-simple");
|
||||
pref("urlclassifier.phishTable", "goog-phish-shavar,goog-phish-proto,test-phish-simple");
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -516,7 +516,6 @@ const gExtensionsNotifications = {
|
|||
container.firstChild.remove();
|
||||
}
|
||||
|
||||
// Strings below to be properly localized in bug 1316996
|
||||
const DEFAULT_EXTENSION_ICON =
|
||||
"chrome://mozapps/skin/extensions/extensionGeneric.svg";
|
||||
let items = 0;
|
||||
|
@ -524,8 +523,10 @@ const gExtensionsNotifications = {
|
|||
if (++items > 4) {
|
||||
break;
|
||||
}
|
||||
|
||||
let button = document.createElement("toolbarbutton");
|
||||
button.setAttribute("label", `"${update.addon.name}" requires new permissions`);
|
||||
let text = gNavigatorBundle.getFormattedString("webextPerms.updateMenuItem", [update.addon.name]);
|
||||
button.setAttribute("label", text);
|
||||
|
||||
let icon = update.addon.iconURL || DEFAULT_EXTENSION_ICON;
|
||||
button.setAttribute("image", icon);
|
||||
|
@ -537,12 +538,19 @@ const gExtensionsNotifications = {
|
|||
container.appendChild(button);
|
||||
}
|
||||
|
||||
let appName;
|
||||
for (let addon of sideloaded) {
|
||||
if (++items > 4) {
|
||||
break;
|
||||
}
|
||||
if (!appName) {
|
||||
let brandBundle = document.getElementById("bundle_brand");
|
||||
appName = brandBundle.getString("brandShortName");
|
||||
}
|
||||
|
||||
let button = document.createElement("toolbarbutton");
|
||||
button.setAttribute("label", `"${addon.name}" added to Firefox`);
|
||||
let text = gNavigatorBundle.getFormattedString("webextPerms.sideloadMenuItem", [addon.name, appName]);
|
||||
button.setAttribute("label", text);
|
||||
|
||||
let icon = addon.iconURL || DEFAULT_EXTENSION_ICON;
|
||||
button.setAttribute("image", icon);
|
||||
|
|
|
@ -3091,7 +3091,11 @@
|
|||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
this.getBrowserForTab(aTab).reload();
|
||||
let browser = this.getBrowserForTab(aTab);
|
||||
// Reset temporary permissions on the current tab. This is done here
|
||||
// because we only want to reset permissions on user reload.
|
||||
SitePermissions.clearTemporaryPermissions(browser);
|
||||
browser.reload();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
|
|
@ -35,9 +35,36 @@ add_task(function* testTempPermissionOnReload() {
|
|||
scope: SitePermissions.SCOPE_TEMPORARY,
|
||||
});
|
||||
|
||||
reloaded = BrowserTestUtils.browserLoaded(browser, false, uri.spec);
|
||||
|
||||
// Reload as a user (should remove the temp permission).
|
||||
EventUtils.synthesizeMouseAtCenter(reloadButton, {});
|
||||
|
||||
yield reloaded;
|
||||
|
||||
Assert.deepEqual(SitePermissions.get(uri, id, browser), {
|
||||
state: SitePermissions.UNKNOWN,
|
||||
scope: SitePermissions.SCOPE_PERSISTENT,
|
||||
});
|
||||
|
||||
// Set the permission again.
|
||||
SitePermissions.set(uri, id, SitePermissions.BLOCK, SitePermissions.SCOPE_TEMPORARY, browser);
|
||||
|
||||
// Open the tab context menu.
|
||||
let contextMenu = document.getElementById("tabContextMenu");
|
||||
let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
|
||||
EventUtils.synthesizeMouseAtCenter(gBrowser.selectedTab, {type: "contextmenu", button: 2});
|
||||
yield popupShownPromise;
|
||||
|
||||
let reloadMenuItem = document.getElementById("context_reloadTab");
|
||||
|
||||
reloaded = BrowserTestUtils.browserLoaded(browser, false, uri.spec);
|
||||
|
||||
// Reload as a user through the context menu (should remove the temp permission).
|
||||
EventUtils.synthesizeMouseAtCenter(reloadMenuItem, {});
|
||||
|
||||
yield reloaded;
|
||||
|
||||
Assert.deepEqual(SitePermissions.get(uri, id, browser), {
|
||||
state: SitePermissions.UNKNOWN,
|
||||
scope: SitePermissions.SCOPE_PERSISTENT,
|
||||
|
|
|
@ -50,4 +50,25 @@ var tests = [
|
|||
this.notification.remove();
|
||||
}
|
||||
},
|
||||
// Test that the space key on an anchor element focuses an active notification
|
||||
{ id: "Test#3",
|
||||
*run() {
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notifyObj.anchorID = "geo-notification-icon";
|
||||
this.notifyObj.addOptions({
|
||||
persistent: true
|
||||
});
|
||||
this.notification = showNotification(this.notifyObj);
|
||||
},
|
||||
*onShown(popup) {
|
||||
checkPopup(popup, this.notifyObj);
|
||||
let anchor = document.getElementById(this.notifyObj.anchorID);
|
||||
anchor.focus();
|
||||
is(document.activeElement, anchor);
|
||||
EventUtils.synthesizeKey(" ", {});
|
||||
is(document.activeElement, popup.childNodes[0].button);
|
||||
this.notification.remove();
|
||||
},
|
||||
onHidden(popup) { }
|
||||
},
|
||||
];
|
||||
|
|
|
@ -33,6 +33,93 @@ xpinstallDisabledMessage=Software installation is currently disabled. Click Enab
|
|||
xpinstallDisabledButton=Enable
|
||||
xpinstallDisabledButton.accesskey=n
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.header)
|
||||
# This string is used as a header in the webextension permissions dialog,
|
||||
# %S is replaced with the localized name of the extension being installed.
|
||||
# See https://bug1308309.bmoattachments.org/attachment.cgi?id=8814612
|
||||
# for an example of the full dialog.
|
||||
# Note, this string will be used as raw markup. Avoid characters like <, >, &
|
||||
webextPerms.header=Add %S?
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.listIntro)
|
||||
# This string will be followed by a list of permissions requested
|
||||
# by the webextension.
|
||||
webextPerms.listIntro=It requires your permission to:
|
||||
webextPerms.add.label=Add
|
||||
webextPerms.add.accessKey=A
|
||||
webextPerms.cancel.label=Cancel
|
||||
webextPerms.cancel.accessKey=C
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.sideloadMenuItem)
|
||||
# %1$S will be replaced with the localized name of the sideloaded add-on.
|
||||
# %2$S will be replace with the name of the application (e.g., Firefox, Nightly)
|
||||
webextPerms.sideloadMenuItem=%1$S added to %2$S
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.sideloadHeader)
|
||||
# This string is used as a header in the webextension permissions dialog
|
||||
# when the extension is side-loaded.
|
||||
# %S is replaced with the localized name of the extension being installed.
|
||||
# Note, this string will be used as raw markup. Avoid characters like <, >, &
|
||||
webextPerms.sideloadHeader=%S added
|
||||
webextPerms.sideloadText=Another program on your computer installed an add-on that may affect your browser. Please review this add-on’s permissions requests and choose to Enable or Disable.
|
||||
|
||||
webextPerms.sideloadEnable.label=Enable
|
||||
webextPerms.sideloadEnable.accessKey=E
|
||||
webextPerms.sideloadDisable.label=Disable
|
||||
webextPerms.sideloadDisable.accessKey=D
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.updateMenuItem)
|
||||
# %S will be replaced with the localized name of the extension which
|
||||
# has been updated.
|
||||
webextPerms.updateMenuItem=%S requires new permissions
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.updateText)
|
||||
# %S is replaced with the localized name of the updated extension.
|
||||
# Note, this string will be used as raw markup. Avoid characters like <, >, &
|
||||
webextPerms.updateText=%S has been updated. You must approve new permissions before the updated version will install. Choosing “Cancel” will maintain your current add-on version.
|
||||
|
||||
webextPerms.updateAccept.label=Update
|
||||
webextPerms.updateAccept.accessKey=U
|
||||
|
||||
webextPerms.description.bookmarks=Read and modify bookmarks
|
||||
webextPerms.description.downloads=Download files and read and modify the browser’s download history
|
||||
webextPerms.description.history=Access browsing history
|
||||
# LOCALIZATION NOTE (webextPerms.description.nativeMessaging)
|
||||
# %S will be replaced with the name of the application
|
||||
webextPerms.description.nativeMessaging=Exchange messages with programs other than %S
|
||||
webextPerms.description.notifications=Display notifications to you
|
||||
webextPerms.description.sessions=Access browser recently closed tabs
|
||||
webextPerms.description.tabs=Access browser tabs
|
||||
webextPerms.description.topSites=Access browsing history
|
||||
webextPerms.description.webNavigation=Access browser activity during navigation
|
||||
|
||||
webextPerms.hostDescription.allUrls=Access your data for all websites
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.hostDescription.wildcard)
|
||||
# %S will be replaced by the DNS domain for which a webextension
|
||||
# is requesting access (e.g., mozilla.org)
|
||||
webextPerms.hostDescription.wildcard=Access your data for sites in the %S domain
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.hostDescription.tooManyWildcards):
|
||||
# Semi-colon list of plural forms.
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
# #1 will be replaced by an integer indicating the number of additional
|
||||
# domains for which this webextension is requesting permission.
|
||||
webextPerms.hostDescription.tooManyWildcards=Access your data in #1 other domain;Access your data in #1 other domains
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.hostDescription.oneSite)
|
||||
# %S will be replaced by the DNS host name for which a webextension
|
||||
# is requesting access (e.g., www.mozilla.org)
|
||||
webextPerms.hostDescription.oneSite=Access your data for %S
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.hostDescription.tooManySites)
|
||||
# Semi-colon list of plural forms.
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
# #1 will be replaced by an integer indicating the number of additional
|
||||
# hosts for which this webextension is requesting permission.
|
||||
webextPerms.hostDescription.tooManySites=Access your data on #1 other site;Access your data on #1 other sites
|
||||
|
||||
|
||||
# LOCALIZATION NOTE (addonDownloadingAndVerifying):
|
||||
# Semicolon-separated list of plural forms. See:
|
||||
# http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
|
|
|
@ -12,6 +12,8 @@ Cu.import("resource://devtools/shared/event-emitter.js");
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
|
||||
"resource://gre/modules/AddonManager.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
|
||||
"resource://gre/modules/PluralForm.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
|
||||
"resource:///modules/RecentWindow.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
|
@ -154,74 +156,98 @@ this.ExtensionsUI = {
|
|||
if (name.length > 50) {
|
||||
name = name.slice(0, 49) + "…";
|
||||
}
|
||||
name = name.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">");
|
||||
|
||||
// The strings below are placeholders, they will switch over to the
|
||||
// bundle.get*String() calls as part of bug 1316996.
|
||||
let addonLabel = `<label class="addon-webext-name">${name}</label>`;
|
||||
let bundle = win.gNavigatorBundle;
|
||||
|
||||
// let bundle = win.gNavigatorBundle;
|
||||
// let header = bundle.getFormattedString("webextPerms.header", [name])
|
||||
// let listHeader = bundle.getString("webextPerms.listHeader");
|
||||
let header = "Add ADDON?".replace("ADDON", name);
|
||||
let header = bundle.getFormattedString("webextPerms.header", [addonLabel]);
|
||||
let text = "";
|
||||
let listHeader = "It can:";
|
||||
let listIntro = bundle.getString("webextPerms.listIntro");
|
||||
|
||||
// let acceptText = bundle.getString("webextPerms.accept.label");
|
||||
// let acceptKey = bundle.getString("webextPerms.accept.accessKey");
|
||||
// let cancelText = bundle.getString("webextPerms.cancel.label");
|
||||
// let cancelKey = bundle.getString("webextPerms.cancel.accessKey");
|
||||
let acceptText = "Add extension";
|
||||
let acceptKey = "A";
|
||||
let cancelText = "Cancel";
|
||||
let cancelKey = "C";
|
||||
let acceptText = bundle.getString("webextPerms.add.label");
|
||||
let acceptKey = bundle.getString("webextPerms.add.accessKey");
|
||||
let cancelText = bundle.getString("webextPerms.cancel.label");
|
||||
let cancelKey = bundle.getString("webextPerms.cancel.accessKey");
|
||||
|
||||
if (info.type == "sideload") {
|
||||
header = `${name} added`;
|
||||
text = "Another program on your computer installed an add-on that may affect your browser. Please review this add-on's permission requests and choose to Enable or Disable";
|
||||
acceptText = "Enable";
|
||||
acceptKey = "E";
|
||||
cancelText = "Disable";
|
||||
cancelKey = "D";
|
||||
header = bundle.getFormattedString("webextPerms.sideloadHeader", [addonLabel]);
|
||||
text = bundle.getString("webextPerms.sideloadText");
|
||||
acceptText = bundle.getString("webextPerms.sideloadEnable.label");
|
||||
acceptKey = bundle.getString("webextPerms.sideloadEnable.accessKey");
|
||||
cancelText = bundle.getString("webextPerms.sideloadDisable.label");
|
||||
cancelKey = bundle.getString("webextPerms.sideloadDisable.accessKey");
|
||||
} else if (info.type == "update") {
|
||||
header = "";
|
||||
text = `${name} has been updated. You must approve new permissions before the updated version will install.`;
|
||||
acceptText = "Update";
|
||||
acceptKey = "U";
|
||||
text = bundle.getFormattedString("webextPerms.updateText", [addonLabel]);
|
||||
acceptText = bundle.getString("webextPerms.updateAccept.label");
|
||||
acceptKey = bundle.getString("webextPerms.updateAccept.accessKey");
|
||||
}
|
||||
|
||||
let formatPermission = perm => {
|
||||
try {
|
||||
// return bundle.getString(`webextPerms.description.${perm}`);
|
||||
return `localized description of permission ${perm}`;
|
||||
} catch (err) {
|
||||
// return bundle.getFormattedString("webextPerms.description.unknown",
|
||||
// [perm]);
|
||||
return `localized description of unknown permission ${perm}`;
|
||||
let msgs = [];
|
||||
for (let permission of perms.permissions) {
|
||||
let key = `webextPerms.description.${permission}`;
|
||||
if (permission == "nativeMessaging") {
|
||||
let brandBundle = win.document.getElementById("bundle_brand");
|
||||
let appName = brandBundle.getString("brandShortName");
|
||||
msgs.push(bundle.getFormattedString(key, [appName]));
|
||||
} else {
|
||||
try {
|
||||
msgs.push(bundle.getString(key));
|
||||
} catch (err) {
|
||||
// We deliberately do not include all permissions in the prompt.
|
||||
// So if we don't find one then just skip it.
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let formatHostPermission = perm => {
|
||||
if (perm == "<all_urls>") {
|
||||
// return bundle.getString("webextPerms.hostDescription.allUrls");
|
||||
return "localized description of <all_urls> host permission";
|
||||
let allUrls = false, wildcards = [], sites = [];
|
||||
for (let permission of perms.hosts) {
|
||||
if (permission == "<all_urls>") {
|
||||
allUrls = true;
|
||||
break;
|
||||
}
|
||||
let match = /^[htps*]+:\/\/([^/]+)\//.exec(perm);
|
||||
let match = /^[htps*]+:\/\/([^/]+)\//.exec(permission);
|
||||
if (!match) {
|
||||
throw new Error("Unparseable host permission");
|
||||
}
|
||||
if (match[1].startsWith("*.")) {
|
||||
let domain = match[1].slice(2);
|
||||
// return bundle.getFormattedString("webextPerms.hostDescription.wildcard", [domain]);
|
||||
return `localized description of wildcard host permission for ${domain}`;
|
||||
if (match[1] == "*") {
|
||||
allUrls = true;
|
||||
} else if (match[1].startsWith("*.")) {
|
||||
wildcards.push(match[1].slice(2));
|
||||
} else {
|
||||
sites.push(match[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (allUrls) {
|
||||
msgs.push(bundle.getString("webextPerms.hostDescription.allUrls"));
|
||||
} else {
|
||||
// Formats a list of host permissions. If we have 4 or fewer, display
|
||||
// them all, otherwise display the first 3 followed by an item that
|
||||
// says "...plus N others"
|
||||
function format(list, itemKey, moreKey) {
|
||||
function formatItems(items) {
|
||||
msgs.push(...items.map(item => bundle.getFormattedString(itemKey, [item])));
|
||||
}
|
||||
if (list.length < 5) {
|
||||
formatItems(list);
|
||||
} else {
|
||||
formatItems(list.slice(0, 3));
|
||||
|
||||
let remaining = list.length - 3;
|
||||
msgs.push(PluralForm.get(remaining, bundle.getString(moreKey))
|
||||
.replace("#1", remaining));
|
||||
}
|
||||
}
|
||||
|
||||
// return bundle.getFormattedString("webextPerms.hostDescription.oneSite", [match[1]]);
|
||||
return `localized description of single host permission for ${match[1]}`;
|
||||
};
|
||||
|
||||
let msgs = [
|
||||
...perms.permissions.map(formatPermission),
|
||||
...perms.hosts.map(formatHostPermission),
|
||||
];
|
||||
format(wildcards, "webextPerms.hostDescription.wildcard",
|
||||
"webextPerms.hostDescription.tooManyWildcards");
|
||||
format(sites, "webextPerms.hostDescription.oneSite",
|
||||
"webextPerms.hostDescription.tooManySites");
|
||||
}
|
||||
|
||||
let popupOptions = {
|
||||
hideClose: true,
|
||||
|
@ -231,21 +257,21 @@ this.ExtensionsUI = {
|
|||
eventCallback(topic) {
|
||||
if (topic == "showing") {
|
||||
let doc = this.browser.ownerDocument;
|
||||
doc.getElementById("addon-webext-perm-header").textContent = header;
|
||||
doc.getElementById("addon-webext-perm-header").innerHTML = header;
|
||||
|
||||
if (text) {
|
||||
doc.getElementById("addon-webext-perm-text").innerHTML = text;
|
||||
}
|
||||
|
||||
let listIntroEl = doc.getElementById("addon-webext-perm-intro");
|
||||
listIntroEl.value = listIntro;
|
||||
listIntroEl.hidden = (msgs.length == 0);
|
||||
|
||||
let list = doc.getElementById("addon-webext-perm-list");
|
||||
while (list.firstChild) {
|
||||
list.firstChild.remove();
|
||||
}
|
||||
|
||||
if (text) {
|
||||
doc.getElementById("addon-webext-perm-text").textContent = text;
|
||||
}
|
||||
|
||||
let listHeaderEl = doc.getElementById("addon-webext-perm-intro");
|
||||
listHeaderEl.value = listHeader;
|
||||
listHeaderEl.hidden = (msgs.length == 0);
|
||||
|
||||
for (let msg of msgs) {
|
||||
let item = doc.createElementNS(HTML_NS, "li");
|
||||
item.textContent = msg;
|
||||
|
|
|
@ -834,10 +834,14 @@ menuitem.bookmark-item {
|
|||
}
|
||||
|
||||
.addon-webext-perm-header {
|
||||
font-weight: bold;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.addon-webext-name {
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Notification icon box */
|
||||
|
||||
.notification-anchor-icon:-moz-focusring {
|
||||
|
|
|
@ -3092,10 +3092,14 @@ menulist.translate-infobar-element > .menulist-dropmarker {
|
|||
}
|
||||
|
||||
.addon-webext-perm-header {
|
||||
font-weight: bold;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.addon-webext-name {
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Status panel */
|
||||
|
||||
.statuspanel-label {
|
||||
|
|
|
@ -2137,10 +2137,14 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
|||
}
|
||||
|
||||
.addon-webext-perm-header {
|
||||
font-weight: bold;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.addon-webext-name {
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Notification icon box */
|
||||
|
||||
.notification-anchor-icon:-moz-focusring {
|
||||
|
|
|
@ -146,7 +146,10 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
|
|||
devtoolsTheme = "light";
|
||||
}
|
||||
|
||||
win.document.documentElement.setAttribute("devtoolstheme", devtoolsTheme);
|
||||
// Style gcli and the splitter between the toolbox and page content. This used to
|
||||
// set the attribute on the browser's root node but that regressed tpaint: bug 1331449.
|
||||
win.document.getElementById("browser-bottombox").setAttribute("devtoolstheme", devtoolsTheme);
|
||||
win.document.getElementById("content").setAttribute("devtoolstheme", devtoolsTheme);
|
||||
|
||||
// If the toolbox color changes and we have the opposite compact theme applied,
|
||||
// change it to match. For example:
|
||||
|
|
|
@ -17,16 +17,22 @@ registerCleanupFunction(() => {
|
|||
add_task(function* testDevtoolsTheme() {
|
||||
info("Checking stylesheet and :root attributes based on devtools theme.");
|
||||
Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "light");
|
||||
is(document.documentElement.getAttribute("devtoolstheme"), "light",
|
||||
"The documentElement has an attribute based on devtools theme.");
|
||||
is(document.getElementById("browser-bottombox").getAttribute("devtoolstheme"), "light",
|
||||
"The element has an attribute based on devtools theme.");
|
||||
is(document.getElementById("content").getAttribute("devtoolstheme"), "light",
|
||||
"The element has an attribute based on devtools theme.");
|
||||
|
||||
Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
|
||||
is(document.documentElement.getAttribute("devtoolstheme"), "dark",
|
||||
"The documentElement has an attribute based on devtools theme.");
|
||||
is(document.getElementById("browser-bottombox").getAttribute("devtoolstheme"), "dark",
|
||||
"The element has an attribute based on devtools theme.");
|
||||
is(document.getElementById("content").getAttribute("devtoolstheme"), "dark",
|
||||
"The element has an attribute based on devtools theme.");
|
||||
|
||||
Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "firebug");
|
||||
is(document.documentElement.getAttribute("devtoolstheme"), "light",
|
||||
"The documentElement has 'light' as a default for the devtoolstheme attribute");
|
||||
is(document.getElementById("browser-bottombox").getAttribute("devtoolstheme"), "light",
|
||||
"The element has 'light' as a default for the devtoolstheme attribute.");
|
||||
is(document.getElementById("content").getAttribute("devtoolstheme"), "light",
|
||||
"The element has 'light' as a default for the devtoolstheme attribute.");
|
||||
});
|
||||
|
||||
add_task(function* testDevtoolsAndCompactThemeSyncing() {
|
||||
|
|
|
@ -64,6 +64,13 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
gBrowser.hideTab(containerTab);
|
||||
let containerBrowser = containerTab.linkedBrowser;
|
||||
|
||||
// Copy tab listener state flags to container tab. Each tab gets its own tab
|
||||
// listener and state flags which cache document loading progress. The state flags
|
||||
// are checked when switching tabs to update the browser UI. The later step of
|
||||
// `swapBrowsersAndCloseOther` will fold the state back into the main tab.
|
||||
let stateFlags = gBrowser._tabListeners.get(tab).mStateFlags;
|
||||
gBrowser._tabListeners.get(containerTab).mStateFlags = stateFlags;
|
||||
|
||||
// 2. Mark the tool tab browser's docshell as active so the viewport frame
|
||||
// is created eagerly and will be ready to swap.
|
||||
// This line is crucial when the tool UI is loaded into a background tab.
|
||||
|
@ -147,11 +154,17 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
gBrowser._swapBrowserDocShells(contentTab, innerBrowser);
|
||||
innerBrowser = null;
|
||||
|
||||
// Copy tab listener state flags to content tab. See similar comment in `start`
|
||||
// above for more details.
|
||||
let stateFlags = gBrowser._tabListeners.get(tab).mStateFlags;
|
||||
gBrowser._tabListeners.get(contentTab).mStateFlags = stateFlags;
|
||||
|
||||
// 5. Force the original browser tab to be remote since web content is
|
||||
// loaded in the child process, and we're about to swap the content
|
||||
// into this tab.
|
||||
gBrowser.updateBrowserRemoteness(tab.linkedBrowser, true,
|
||||
contentBrowser.remoteType);
|
||||
gBrowser.updateBrowserRemoteness(tab.linkedBrowser, true, {
|
||||
remoteType: contentBrowser.remoteType,
|
||||
});
|
||||
|
||||
// 6. Swap the content into the original browser tab and close the
|
||||
// temporary tab used to hold the content via
|
||||
|
|
|
@ -192,8 +192,8 @@ function dragElementBy(selector, x, y, win) {
|
|||
let { Simulate } = React.addons.TestUtils;
|
||||
let rect = getElRect(selector, win);
|
||||
let startPoint = {
|
||||
clientX: rect.left + Math.floor(rect.width / 2),
|
||||
clientY: rect.top + Math.floor(rect.height / 2),
|
||||
clientX: Math.floor(rect.left + rect.width / 2),
|
||||
clientY: Math.floor(rect.top + rect.height / 2),
|
||||
};
|
||||
let endPoint = [ startPoint.clientX + x, startPoint.clientY + y ];
|
||||
|
||||
|
|
|
@ -933,8 +933,8 @@ OutputPanel.prototype._init = function (devtoolbar) {
|
|||
so it can be styled correctly. */
|
||||
OutputPanel.prototype._copyTheme = function () {
|
||||
if (this.document) {
|
||||
let theme =
|
||||
this._devtoolbar._doc.documentElement.getAttribute("devtoolstheme");
|
||||
let theme = this._devtoolbar._doc.getElementById("browser-bottombox")
|
||||
.getAttribute("devtoolstheme");
|
||||
this.document.documentElement.setAttribute("devtoolstheme", theme);
|
||||
}
|
||||
};
|
||||
|
@ -1253,8 +1253,8 @@ TooltipPanel.prototype._init = function (devtoolbar) {
|
|||
so it can be styled correctly. */
|
||||
TooltipPanel.prototype._copyTheme = function () {
|
||||
if (this.document) {
|
||||
let theme =
|
||||
this._devtoolbar._doc.documentElement.getAttribute("devtoolstheme");
|
||||
let theme = this._devtoolbar._doc.getElementById("browser-bottombox")
|
||||
.getAttribute("devtoolstheme");
|
||||
this.document.documentElement.setAttribute("devtoolstheme", theme);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
/* NOTE: THESE NEED TO STAY IN SYNC WITH LIGHT-THEME.CSS AND DARK-THEME.CSS.
|
||||
We are copy/pasting variables from light-theme and dark-theme,
|
||||
since they aren't loaded in this context (within browser.css). */
|
||||
:root[devtoolstheme="light"] #developer-toolbar {
|
||||
#browser-bottombox[devtoolstheme="light"] #developer-toolbar {
|
||||
--gcli-background-color: #fcfcfc; /* --theme-tab-toolbar-background */
|
||||
--gcli-input-background: #fcfcfc; /* --theme-toolbar-background */
|
||||
--gcli-input-focused-background: #ffffff; /* --theme-sidebar-background */
|
||||
|
@ -21,7 +21,7 @@
|
|||
--command-line-image-focus: url(chrome://devtools/skin/images/commandline-icon.svg#light-theme-focus); /* --theme-command-line-image-focus */
|
||||
}
|
||||
|
||||
:root[devtoolstheme="dark"] #developer-toolbar {
|
||||
#browser-bottombox[devtoolstheme="dark"] #developer-toolbar {
|
||||
--gcli-background-color: #272b35; /* --theme-toolbar-background */
|
||||
--gcli-input-background: #272b35; /* --theme-tab-toolbar-background */
|
||||
--gcli-input-focused-background: #272b35; /* --theme-tab-toolbar-background */
|
||||
|
@ -54,8 +54,8 @@
|
|||
margin: auto 10px;
|
||||
}
|
||||
|
||||
:root[devtoolstheme="light"] #developer-toolbar > .developer-toolbar-button:not([checked=true]) > image,
|
||||
:root[devtoolstheme="light"] .gclitoolbar-input-node:not([focused=true])::before {
|
||||
#browser-bottombox[devtoolstheme="light"] #developer-toolbar > .developer-toolbar-button:not([checked=true]) > image,
|
||||
#browser-bottombox[devtoolstheme="light"] .gclitoolbar-input-node:not([focused=true])::before {
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@
|
|||
}
|
||||
|
||||
/* The toolkit close button is low contrast in the dark theme so invert it. */
|
||||
:root[devtoolstheme="dark"] #developer-toolbar > .close-icon:not(:hover) > image {
|
||||
#browser-bottombox[devtoolstheme="dark"] #developer-toolbar > .close-icon:not(:hover) > image {
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,12 @@
|
|||
--devtools-splitter-inline-end-width: 4px;
|
||||
}
|
||||
|
||||
:root[devtoolstheme="light"] {
|
||||
#content[devtoolstheme="light"] {
|
||||
/* These variables are used in browser.xul but inside the toolbox they are overridden by --theme-splitter-color */
|
||||
--devtools-splitter-color: #dde1e4;
|
||||
}
|
||||
|
||||
:root[devtoolstheme="dark"],
|
||||
:root[devtoolstheme="firebug"] {
|
||||
#content[devtoolstheme="dark"] {
|
||||
--devtools-splitter-color: #42484f;
|
||||
}
|
||||
|
||||
|
|
|
@ -354,6 +354,11 @@ AudioStream::Init(uint32_t aNumChannels, uint32_t aRate,
|
|||
return NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR;
|
||||
}
|
||||
|
||||
cubeb_channel_layout layout;
|
||||
int r = cubeb_get_preferred_channel_layout(cubebContext, &layout);
|
||||
MOZ_ASSERT(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
params.layout = (r == CUBEB_OK) ? layout : CUBEB_LAYOUT_UNDEFINED;
|
||||
|
||||
return OpenCubeb(cubebContext, params, startTime, CubebUtils::GetFirstStream());
|
||||
}
|
||||
|
||||
|
|
|
@ -639,6 +639,11 @@ AudioCallbackDriver::Init()
|
|||
output.format = CUBEB_SAMPLE_FLOAT32NE;
|
||||
}
|
||||
|
||||
cubeb_channel_layout layout;
|
||||
int r = cubeb_get_preferred_channel_layout(cubebContext, &layout);
|
||||
MOZ_ASSERT(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
output.layout = (r == CUBEB_OK) ? layout : CUBEB_LAYOUT_UNDEFINED;
|
||||
|
||||
Maybe<uint32_t> latencyPref = CubebUtils::GetCubebMSGLatencyInFrames();
|
||||
if (latencyPref) {
|
||||
latency_frames = latencyPref.value();
|
||||
|
@ -658,6 +663,7 @@ AudioCallbackDriver::Init()
|
|||
|
||||
input = output;
|
||||
input.channels = mInputChannels; // change to support optional stereo capture
|
||||
input.layout = CUBEB_LAYOUT_MONO;
|
||||
|
||||
cubeb_stream* stream = nullptr;
|
||||
CubebUtils::AudioDeviceID input_id = nullptr, output_id = nullptr;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// |jit-test| test-also-wasm-baseline; exitstatus: 3
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
if (!wasmIsSupported())
|
||||
quit(3);
|
||||
|
||||
var g = newGlobal();
|
||||
g.parent = this;
|
||||
g.eval("new Debugger(parent).onExceptionUnwind = function () { some_error; };");
|
||||
|
||||
var module = new WebAssembly.Module(wasmTextToBinary(`
|
||||
(module
|
||||
(import $imp "a" "b" (result i32))
|
||||
(func $call (result i32) (call 0))
|
||||
(export "call" $call)
|
||||
)`));
|
||||
|
||||
var instance = new WebAssembly.Instance(module, { a: { b: () => {
|
||||
some_other_error;
|
||||
}}});
|
||||
instance.exports.call();
|
|
@ -151,12 +151,16 @@ WasmHandleThrow()
|
|||
|
||||
DebugFrame* frame = iter.debugFrame();
|
||||
|
||||
JSTrapStatus status = Debugger::onExceptionUnwind(cx, frame);
|
||||
if (status == JSTRAP_RETURN) {
|
||||
// Unexpected trap return -- raising error since throw recovery
|
||||
// is not yet implemented in the wasm baseline.
|
||||
// TODO properly handle JSTRAP_RETURN and resume wasm execution.
|
||||
JS_ReportErrorASCII(cx, "Unexpected resumption value from onExceptionUnwind");
|
||||
// Assume JSTRAP_ERROR status if no exception is pending --
|
||||
// no onExceptionUnwind handlers must be fired.
|
||||
if (cx->isExceptionPending()) {
|
||||
JSTrapStatus status = Debugger::onExceptionUnwind(cx, frame);
|
||||
if (status == JSTRAP_RETURN) {
|
||||
// Unexpected trap return -- raising error since throw recovery
|
||||
// is not yet implemented in the wasm baseline.
|
||||
// TODO properly handle JSTRAP_RETURN and resume wasm execution.
|
||||
JS_ReportErrorASCII(cx, "Unexpected resumption value from onExceptionUnwind");
|
||||
}
|
||||
}
|
||||
|
||||
bool ok = Debugger::onLeaveFrame(cx, frame, nullptr, false);
|
||||
|
|
|
@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
|
|||
|
||||
The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
|
||||
|
||||
The git commit ID used was 051cd8478dd48a18e2e91e5f07837640f40618c1.
|
||||
The git commit ID used was d96e35f02dbb9a093e5bfdff4f2948b7a6e9d3f9.
|
||||
|
|
|
@ -16,6 +16,13 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
template<typename T, size_t N>
|
||||
constexpr size_t
|
||||
ARRAY_LENGTH(T(&)[N])
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
void delay(unsigned int ms)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
|
@ -30,6 +37,34 @@ void delay(unsigned int ms)
|
|||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char const * name;
|
||||
unsigned int const channels;
|
||||
cubeb_channel_layout const layout;
|
||||
} layout_info;
|
||||
|
||||
layout_info const layout_infos[CUBEB_LAYOUT_MAX] = {
|
||||
{ "undefined", 0, CUBEB_LAYOUT_UNDEFINED },
|
||||
{ "dual mono", 2, CUBEB_LAYOUT_DUAL_MONO },
|
||||
{ "dual mono lfe", 3, CUBEB_LAYOUT_DUAL_MONO_LFE },
|
||||
{ "mono", 1, CUBEB_LAYOUT_MONO },
|
||||
{ "mono lfe", 2, CUBEB_LAYOUT_MONO_LFE },
|
||||
{ "stereo", 2, CUBEB_LAYOUT_STEREO },
|
||||
{ "stereo lfe", 3, CUBEB_LAYOUT_STEREO_LFE },
|
||||
{ "3f", 3, CUBEB_LAYOUT_3F },
|
||||
{ "3f lfe", 4, CUBEB_LAYOUT_3F_LFE },
|
||||
{ "2f1", 3, CUBEB_LAYOUT_2F1 },
|
||||
{ "2f1 lfe", 4, CUBEB_LAYOUT_2F1_LFE },
|
||||
{ "3f1", 4, CUBEB_LAYOUT_3F1 },
|
||||
{ "3f1 lfe", 5, CUBEB_LAYOUT_3F1_LFE },
|
||||
{ "2f2", 4, CUBEB_LAYOUT_2F2 },
|
||||
{ "2f2 lfe", 5, CUBEB_LAYOUT_2F2_LFE },
|
||||
{ "3f2", 5, CUBEB_LAYOUT_3F2 },
|
||||
{ "3f2 lfe", 6, CUBEB_LAYOUT_3F2_LFE },
|
||||
{ "3f3r lfe", 7, CUBEB_LAYOUT_3F3R_LFE },
|
||||
{ "3f4 lfe", 8, CUBEB_LAYOUT_3F4_LFE }
|
||||
};
|
||||
|
||||
int has_available_input_device(cubeb * ctx)
|
||||
{
|
||||
cubeb_device_collection * devices;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define NELEMS(x) ((int) (sizeof(x) / sizeof(x[0])))
|
||||
#define VOLUME 0.2
|
||||
|
||||
float get_frequency(int channel_index)
|
||||
|
@ -118,7 +117,7 @@ int supports_channel_count(const char* backend_id, int nchannels)
|
|||
(strcmp(backend_id, "opensl") != 0 && strcmp(backend_id, "audiotrack") != 0);
|
||||
}
|
||||
|
||||
int run_test(int num_channels, int sampling_rate, int is_float)
|
||||
int run_test(int num_channels, layout_info layout, int sampling_rate, int is_float)
|
||||
{
|
||||
int r = CUBEB_OK;
|
||||
|
||||
|
@ -142,12 +141,13 @@ int run_test(int num_channels, int sampling_rate, int is_float)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Testing %d channel(s), %d Hz, %s (%s)\n", num_channels, sampling_rate, is_float ? "float" : "short", cubeb_get_backend_id(ctx));
|
||||
fprintf(stderr, "Testing %d channel(s), layout: %s, %d Hz, %s (%s)\n", num_channels, layout.name, sampling_rate, is_float ? "float" : "short", cubeb_get_backend_id(ctx));
|
||||
|
||||
cubeb_stream_params params;
|
||||
params.format = is_float ? CUBEB_SAMPLE_FLOAT32NE : CUBEB_SAMPLE_S16NE;
|
||||
params.rate = sampling_rate;
|
||||
params.channels = num_channels;
|
||||
params.layout = layout.layout;
|
||||
|
||||
synth = synth_create(params.channels, params.rate);
|
||||
if (synth == NULL) {
|
||||
|
@ -200,6 +200,7 @@ int run_panning_volume_test(int is_float)
|
|||
params.format = is_float ? CUBEB_SAMPLE_FLOAT32NE : CUBEB_SAMPLE_S16NE;
|
||||
params.rate = 44100;
|
||||
params.channels = 2;
|
||||
params.layout = CUBEB_LAYOUT_STEREO;
|
||||
|
||||
synth = synth_create(params.channels, params.rate);
|
||||
if (synth == NULL) {
|
||||
|
@ -259,7 +260,7 @@ TEST(cubeb, run_panning_volume_test_float)
|
|||
|
||||
TEST(cubeb, run_channel_rate_test)
|
||||
{
|
||||
int channel_values[] = {
|
||||
unsigned int channel_values[] = {
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
|
@ -274,13 +275,16 @@ TEST(cubeb, run_channel_rate_test)
|
|||
48000,
|
||||
};
|
||||
|
||||
for(int j = 0; j < NELEMS(channel_values); ++j) {
|
||||
for(int i = 0; i < NELEMS(freq_values); ++i) {
|
||||
for(unsigned int j = 0; j < ARRAY_LENGTH(channel_values); ++j) {
|
||||
for(unsigned int i = 0; i < ARRAY_LENGTH(freq_values); ++i) {
|
||||
ASSERT_TRUE(channel_values[j] < MAX_NUM_CHANNELS);
|
||||
fprintf(stderr, "--------------------------\n");
|
||||
ASSERT_EQ(run_test(channel_values[j], freq_values[i], 0), CUBEB_OK);
|
||||
ASSERT_EQ(run_test(channel_values[j], freq_values[i], 1), CUBEB_OK);
|
||||
for (unsigned int k = 0 ; k < ARRAY_LENGTH(layout_infos); ++k ) {
|
||||
if (layout_infos[k].channels == channel_values[j]) {
|
||||
ASSERT_EQ(run_test(channel_values[j], layout_infos[k], freq_values[i], 0), CUBEB_OK);
|
||||
ASSERT_EQ(run_test(channel_values[j], layout_infos[k], freq_values[i], 1), CUBEB_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,9 +108,11 @@ TEST(cubeb, duplex)
|
|||
input_params.format = STREAM_FORMAT;
|
||||
input_params.rate = 48000;
|
||||
input_params.channels = 1;
|
||||
input_params.layout = CUBEB_LAYOUT_MONO;
|
||||
output_params.format = STREAM_FORMAT;
|
||||
output_params.rate = 48000;
|
||||
output_params.channels = 2;
|
||||
output_params.layout = CUBEB_LAYOUT_STEREO;
|
||||
|
||||
r = cubeb_get_min_latency(ctx, output_params, &latency_frames);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ TEST(cubeb, latency)
|
|||
uint32_t max_channels;
|
||||
uint32_t preferred_rate;
|
||||
uint32_t latency_frames;
|
||||
cubeb_channel_layout layout;
|
||||
|
||||
r = cubeb_init(&ctx, "Cubeb audio test");
|
||||
ASSERT_EQ(r, CUBEB_OK);
|
||||
|
@ -25,10 +26,17 @@ TEST(cubeb, latency)
|
|||
ASSERT_GT(preferred_rate, 0u);
|
||||
}
|
||||
|
||||
r = cubeb_get_preferred_channel_layout(ctx, &layout);
|
||||
ASSERT_TRUE(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
|
||||
cubeb_stream_params params = {
|
||||
CUBEB_SAMPLE_FLOAT32NE,
|
||||
preferred_rate,
|
||||
max_channels
|
||||
max_channels,
|
||||
(r == CUBEB_OK) ? layout : CUBEB_LAYOUT_UNDEFINED
|
||||
#if defined(__ANDROID__)
|
||||
, CUBEB_STREAM_TYPE_MUSIC
|
||||
#endif
|
||||
};
|
||||
r = cubeb_get_min_latency(ctx, params, &latency_frames);
|
||||
ASSERT_TRUE(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright © 2016 Mozilla Foundation
|
||||
*
|
||||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
#include "gtest/gtest.h"
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "cubeb_mixer.h"
|
||||
#include "common.h"
|
||||
#include <vector>
|
||||
|
||||
using std::vector;
|
||||
|
||||
#define STREAM_FREQUENCY 48000
|
||||
#define STREAM_FORMAT CUBEB_SAMPLE_FLOAT32LE
|
||||
|
||||
float const M = 1.0f; // Mono
|
||||
float const L = 2.0f; // Left
|
||||
float const R = 3.0f; // Right
|
||||
float const C = 4.0f; // Center
|
||||
float const LS = 5.0f; // Left Surround
|
||||
float const RS = 6.0f; // Right Surround
|
||||
float const RLS = 7.0f; // Rear Left Surround
|
||||
float const RC = 8.0f; // Rear Center
|
||||
float const RRS = 9.0f; // Rear Right Surround
|
||||
float const LFE = 10.0f; // Low Frequency Effects
|
||||
|
||||
float const INV_SQRT_2 = 0.707106f; // 1/sqrt(2)
|
||||
static float const DOWNMIX_3F2_RESULTS[2][12][5] = {
|
||||
// 3F2
|
||||
{
|
||||
{ INV_SQRT_2*(L+R) + C + 0.5f*(LS+RS) }, // Mono
|
||||
{ INV_SQRT_2*(L+R) + C + 0.5f*(LS+RS), 0 }, // Mono-LFE
|
||||
{ L + INV_SQRT_2*(C+LS), R + INV_SQRT_2*(C+RS) }, // Stereo
|
||||
{ L + INV_SQRT_2*(C+LS), R + INV_SQRT_2*(C+RS), 0 }, // Stereo-LFE
|
||||
{ L + INV_SQRT_2*LS, R + INV_SQRT_2*RS, C }, // 3F
|
||||
{ L + INV_SQRT_2*LS, R + INV_SQRT_2*RS, C, 0 }, // 3F-LFE
|
||||
{ L + C*INV_SQRT_2, R + C*INV_SQRT_2, INV_SQRT_2*(LS+RS) }, // 2F1
|
||||
{ L + C*INV_SQRT_2, R + C*INV_SQRT_2, 0, INV_SQRT_2*(LS+RS) }, // 2F1-LFE
|
||||
{ L, R, C, INV_SQRT_2*(LS+RS) }, // 3F1
|
||||
{ L, R, C, 0, INV_SQRT_2*(LS+RS) }, // 3F1-LFE
|
||||
{ L + INV_SQRT_2*C, R + INV_SQRT_2*C, LS, RS }, // 2F2
|
||||
{ L + INV_SQRT_2*C, R + INV_SQRT_2*C, 0, LS, RS } // 2F2-LFE
|
||||
},
|
||||
// 3F2-LFE
|
||||
{
|
||||
{ INV_SQRT_2*(L+R) + C + 0.5f*(LS+RS) }, // Mono
|
||||
{ INV_SQRT_2*(L+R) + C + 0.5f*(LS+RS), LFE }, // Mono-LFE
|
||||
{ L + INV_SQRT_2*(C+LS), R + INV_SQRT_2*(C+RS) }, // Stereo
|
||||
{ L + INV_SQRT_2*(C+LS), R + INV_SQRT_2*(C+RS), LFE }, // Stereo-LFE
|
||||
{ L + INV_SQRT_2*LS, R + INV_SQRT_2*RS, C }, // 3F
|
||||
{ L + INV_SQRT_2*LS, R + INV_SQRT_2*RS, C, LFE }, // 3F-LFE
|
||||
{ L + C*INV_SQRT_2, R + C*INV_SQRT_2, INV_SQRT_2*(LS+RS) }, // 2F1
|
||||
{ L + C*INV_SQRT_2, R + C*INV_SQRT_2, LFE, INV_SQRT_2*(LS+RS) }, // 2F1-LFE
|
||||
{ L, R, C, INV_SQRT_2*(LS+RS) }, // 3F1
|
||||
{ L, R, C, LFE, INV_SQRT_2*(LS+RS) }, // 3F1-LFE
|
||||
{ L + INV_SQRT_2*C, R + INV_SQRT_2*C, LS, RS }, // 2F2
|
||||
{ L + INV_SQRT_2*C, R + INV_SQRT_2*C, LFE, LS, RS } // 2F2-LFE
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
cubeb_channel_layout layout;
|
||||
float data[10];
|
||||
} audio_input;
|
||||
|
||||
audio_input audio_inputs[CUBEB_LAYOUT_MAX] = {
|
||||
{ CUBEB_LAYOUT_UNDEFINED, { } },
|
||||
{ CUBEB_LAYOUT_DUAL_MONO, { L, R } },
|
||||
{ CUBEB_LAYOUT_DUAL_MONO_LFE, { L, R, LFE } },
|
||||
{ CUBEB_LAYOUT_MONO, { M } },
|
||||
{ CUBEB_LAYOUT_MONO_LFE, { M, LFE } },
|
||||
{ CUBEB_LAYOUT_STEREO, { L, R } },
|
||||
{ CUBEB_LAYOUT_STEREO_LFE, { L, R, LFE } },
|
||||
{ CUBEB_LAYOUT_3F, { L, R, C } },
|
||||
{ CUBEB_LAYOUT_3F_LFE, { L, R, C, LFE } },
|
||||
{ CUBEB_LAYOUT_2F1, { L, R, RC } },
|
||||
{ CUBEB_LAYOUT_2F1_LFE, { L, R, LFE, RC } },
|
||||
{ CUBEB_LAYOUT_3F1, { L, R, C, RC } },
|
||||
{ CUBEB_LAYOUT_3F1_LFE, { L, R, C, LFE, RC } },
|
||||
{ CUBEB_LAYOUT_2F2, { L, R, LS, RS } },
|
||||
{ CUBEB_LAYOUT_2F2_LFE, { L, R, LFE, LS, RS } },
|
||||
{ CUBEB_LAYOUT_3F2, { L, R, C, LS, RS } },
|
||||
{ CUBEB_LAYOUT_3F2_LFE, { L, R, C, LFE, LS, RS } },
|
||||
{ CUBEB_LAYOUT_3F3R_LFE, { L, R, C, LFE, RC, LS, RS } },
|
||||
{ CUBEB_LAYOUT_3F4_LFE, { L, R, C, LFE, RLS, RRS, LS, RS } }
|
||||
};
|
||||
|
||||
void
|
||||
downmix_test(float const * data, cubeb_channel_layout in_layout, cubeb_channel_layout out_layout)
|
||||
{
|
||||
if (in_layout == CUBEB_LAYOUT_UNDEFINED) {
|
||||
return; // Only possible output layout would be UNDEFINED.
|
||||
}
|
||||
|
||||
cubeb_stream_params in_params = {
|
||||
STREAM_FORMAT,
|
||||
STREAM_FREQUENCY,
|
||||
layout_infos[in_layout].channels,
|
||||
in_layout
|
||||
#if defined(__ANDROID__)
|
||||
, CUBEB_STREAM_TYPE_MUSIC
|
||||
#endif
|
||||
};
|
||||
|
||||
cubeb_stream_params out_params = {
|
||||
STREAM_FORMAT,
|
||||
STREAM_FREQUENCY,
|
||||
// To downmix audio data with undefined layout, its channel number must be
|
||||
// smaller than or equal to the input channels.
|
||||
(out_layout == CUBEB_LAYOUT_UNDEFINED) ?
|
||||
layout_infos[in_layout].channels : layout_infos[out_layout].channels,
|
||||
out_layout
|
||||
#if defined(__ANDROID__)
|
||||
, CUBEB_STREAM_TYPE_MUSIC
|
||||
#endif
|
||||
};
|
||||
|
||||
if (!cubeb_should_downmix(&in_params, &out_params)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Downmix from %s to %s\n", layout_infos[in_layout].name, layout_infos[out_layout].name);
|
||||
|
||||
unsigned int const inframes = 10;
|
||||
vector<float> in(in_params.channels * inframes);
|
||||
vector<float> out(out_params.channels * inframes);
|
||||
|
||||
for (unsigned int offset = 0 ; offset < inframes * in_params.channels ; offset += in_params.channels) {
|
||||
for (unsigned int i = 0 ; i < in_params.channels ; ++i) {
|
||||
in[offset + i] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
cubeb_downmix_float(in.data(), inframes, out.data(), in_params.channels, out_params.channels, in_params.layout, out_params.layout);
|
||||
|
||||
uint32_t in_layout_mask = 0;
|
||||
for (unsigned int i = 0 ; i < in_params.channels; ++i) {
|
||||
in_layout_mask |= 1 << CHANNEL_INDEX_TO_ORDER[in_layout][i];
|
||||
}
|
||||
|
||||
uint32_t out_layout_mask = 0;
|
||||
for (unsigned int i = 0 ; out_layout != CUBEB_LAYOUT_UNDEFINED && i < out_params.channels; ++i) {
|
||||
out_layout_mask |= 1 << CHANNEL_INDEX_TO_ORDER[out_layout][i];
|
||||
}
|
||||
|
||||
for (unsigned int i = 0 ; i < inframes * out_params.channels ; ++i) {
|
||||
unsigned int index = i % out_params.channels;
|
||||
|
||||
// downmix_3f2
|
||||
if ((in_layout == CUBEB_LAYOUT_3F2 || in_layout == CUBEB_LAYOUT_3F2_LFE) &&
|
||||
out_layout >= CUBEB_LAYOUT_MONO && out_layout <= CUBEB_LAYOUT_2F2_LFE) {
|
||||
auto & downmix_results = DOWNMIX_3F2_RESULTS[in_layout - CUBEB_LAYOUT_3F2][out_layout - CUBEB_LAYOUT_MONO];
|
||||
fprintf(stderr, "[3f2] Expect: %lf, Get: %lf\n", downmix_results[index], out[index]);
|
||||
ASSERT_EQ(out[index], downmix_results[index]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// mix_remap
|
||||
if (out_layout_mask & in_layout_mask) {
|
||||
uint32_t mask = 1 << CHANNEL_INDEX_TO_ORDER[out_layout][index];
|
||||
fprintf(stderr, "[map channels] Expect: %lf, Get: %lf\n", (mask & in_layout_mask) ? audio_inputs[out_layout].data[index] : 0, out[index]);
|
||||
ASSERT_EQ(out[index], (mask & in_layout_mask) ? audio_inputs[out_layout].data[index] : 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// downmix_fallback
|
||||
fprintf(stderr, "[fallback] Expect: %lf, Get: %lf\n", audio_inputs[in_layout].data[index], out[index]);
|
||||
ASSERT_EQ(out[index], audio_inputs[in_layout].data[index]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(cubeb, run_mixing_test)
|
||||
{
|
||||
for (unsigned int i = 0 ; i < ARRAY_LENGTH(audio_inputs) ; ++i) {
|
||||
for (unsigned int j = 0 ; j < ARRAY_LENGTH(layout_infos) ; ++j) {
|
||||
downmix_test(audio_inputs[i].data, audio_inputs[i].layout, layout_infos[j].layout);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -95,6 +95,7 @@ TEST(cubeb, record)
|
|||
params.format = STREAM_FORMAT;
|
||||
params.rate = SAMPLE_FREQUENCY;
|
||||
params.channels = 1;
|
||||
params.layout = CUBEB_LAYOUT_MONO;
|
||||
|
||||
r = cubeb_stream_init(ctx, &stream, "Cubeb record (mono)", NULL, ¶ms, NULL, nullptr,
|
||||
4096, data_cb_record, state_cb_record, &stream_state);
|
||||
|
|
|
@ -286,7 +286,6 @@ long data_cb_resampler(cubeb_stream * /*stm*/, void * user_ptr,
|
|||
const float * in = reinterpret_cast<const float*>(input_buffer);
|
||||
float * out = reinterpret_cast<float*>(output_buffer);
|
||||
|
||||
|
||||
state->input.push(in, frame_count * state->input_channels);
|
||||
|
||||
/* Check how much output frames we need to write */
|
||||
|
@ -362,7 +361,6 @@ void test_resampler_duplex(uint32_t input_channels, uint32_t output_channels,
|
|||
fill_with_sine(expected_resampled_output.data() + latency,
|
||||
output_rate, output_channels, output_rate * duration_s - latency, 0);
|
||||
|
||||
|
||||
while (state.output_phase_index != state.max_output_phase_index) {
|
||||
uint32_t leftover_samples = input_buffer.length() * input_channels;
|
||||
input_buffer.reserve(input_array_frame_count);
|
||||
|
|
|
@ -18,19 +18,13 @@
|
|||
#define STREAM_RATE 44100
|
||||
#define STREAM_LATENCY 100 * STREAM_RATE / 1000
|
||||
#define STREAM_CHANNELS 1
|
||||
#define STREAM_LAYOUT CUBEB_LAYOUT_MONO
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
#define STREAM_FORMAT CUBEB_SAMPLE_FLOAT32LE
|
||||
#else
|
||||
#define STREAM_FORMAT CUBEB_SAMPLE_S16LE
|
||||
#endif
|
||||
|
||||
template<typename T, size_t N>
|
||||
constexpr size_t
|
||||
ARRAY_LENGTH(T(&)[N])
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
int is_windows_7()
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
|
@ -95,7 +89,6 @@ TEST(cubeb, init_destroy_context)
|
|||
ASSERT_EQ(r, CUBEB_OK);
|
||||
ASSERT_NE(ctx, nullptr);
|
||||
|
||||
|
||||
backend_id = cubeb_get_backend_id(ctx);
|
||||
ASSERT_TRUE(backend_id);
|
||||
|
||||
|
@ -138,6 +131,7 @@ TEST(cubeb, context_variables)
|
|||
params.channels = STREAM_CHANNELS;
|
||||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.layout = STREAM_LAYOUT;
|
||||
#if defined(__ANDROID__)
|
||||
params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
|
||||
#endif
|
||||
|
@ -170,6 +164,7 @@ TEST(cubeb, init_destroy_stream)
|
|||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.channels = STREAM_CHANNELS;
|
||||
params.layout = STREAM_LAYOUT;
|
||||
#if defined(__ANDROID__)
|
||||
params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
|
||||
#endif
|
||||
|
@ -198,6 +193,7 @@ TEST(cubeb, init_destroy_multiple_streams)
|
|||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.channels = STREAM_CHANNELS;
|
||||
params.layout = STREAM_LAYOUT;
|
||||
#if defined(__ANDROID__)
|
||||
params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
|
||||
#endif
|
||||
|
@ -230,6 +226,7 @@ TEST(cubeb, configure_stream)
|
|||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.channels = 2; // panning
|
||||
params.layout = CUBEB_LAYOUT_STEREO;
|
||||
#if defined(__ANDROID__)
|
||||
params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
|
||||
#endif
|
||||
|
@ -265,6 +262,7 @@ test_init_start_stop_destroy_multiple_streams(int early, int delay_ms)
|
|||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.channels = STREAM_CHANNELS;
|
||||
params.layout = STREAM_LAYOUT;
|
||||
#if defined(__ANDROID__)
|
||||
params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
|
||||
#endif
|
||||
|
@ -280,7 +278,6 @@ test_init_start_stop_destroy_multiple_streams(int early, int delay_ms)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (!early) {
|
||||
for (i = 0; i < ARRAY_LENGTH(stream); ++i) {
|
||||
r = cubeb_stream_start(stream[i]);
|
||||
|
@ -352,6 +349,7 @@ TEST(cubeb, init_destroy_multiple_contexts_and_streams)
|
|||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.channels = STREAM_CHANNELS;
|
||||
params.layout = STREAM_LAYOUT;
|
||||
#if defined(__ANDROID__)
|
||||
params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
|
||||
#endif
|
||||
|
@ -392,6 +390,7 @@ TEST(cubeb, basic_stream_operations)
|
|||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.channels = STREAM_CHANNELS;
|
||||
params.layout = STREAM_LAYOUT;
|
||||
#if defined(__ANDROID__)
|
||||
params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
|
||||
#endif
|
||||
|
@ -442,6 +441,7 @@ TEST(cubeb, stream_position)
|
|||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.channels = STREAM_CHANNELS;
|
||||
params.layout = STREAM_LAYOUT;
|
||||
#if defined(__ANDROID__)
|
||||
params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
|
||||
#endif
|
||||
|
@ -581,6 +581,7 @@ TEST(cubeb, drain)
|
|||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.channels = STREAM_CHANNELS;
|
||||
params.layout = STREAM_LAYOUT;
|
||||
#if defined(__ANDROID__)
|
||||
params.stream_type = CUBEB_STREAM_TYPE_MUSIC;
|
||||
#endif
|
||||
|
|
|
@ -110,6 +110,7 @@ TEST(cubeb, tone)
|
|||
params.format = STREAM_FORMAT;
|
||||
params.rate = SAMPLE_FREQUENCY;
|
||||
params.channels = 1;
|
||||
params.layout = CUBEB_LAYOUT_MONO;
|
||||
|
||||
user_data = (struct cb_user_data *) malloc(sizeof(*user_data));
|
||||
if (user_data == NULL) {
|
||||
|
|
|
@ -176,12 +176,71 @@ typedef enum {
|
|||
CUBEB_LOG_VERBOSE = 2, /**< Verbose logging of callbacks, can have performance implications. */
|
||||
} cubeb_log_level;
|
||||
|
||||
/** SMPTE channel layout (also known as wave order)
|
||||
* DUAL-MONO L R
|
||||
* DUAL-MONO-LFE L R LFE
|
||||
* MONO M
|
||||
* MONO-LFE M LFE
|
||||
* STEREO L R
|
||||
* STEREO-LFE L R LFE
|
||||
* 3F L R C
|
||||
* 3F-LFE L R C LFE
|
||||
* 2F1 L R S
|
||||
* 2F1-LFE L R LFE S
|
||||
* 3F1 L R C S
|
||||
* 3F1-LFE L R C LFE S
|
||||
* 2F2 L R LS RS
|
||||
* 2F2-LFE L R LFE LS RS
|
||||
* 3F2 L R C LS RS
|
||||
* 3F2-LFE L R C LFE LS RS
|
||||
* 3F3R-LFE L R C LFE RC LS RS
|
||||
* 3F4-LFE L R C LFE RLS RRS LS RS
|
||||
*
|
||||
* The abbreviation of channel name is defined in following table:
|
||||
* Abbr Channel name
|
||||
* ---------------------------
|
||||
* M Mono
|
||||
* L Left
|
||||
* R Right
|
||||
* C Center
|
||||
* LS Left Surround
|
||||
* RS Right Surround
|
||||
* RLS Rear Left Surround
|
||||
* RC Rear Center
|
||||
* RRS Rear Right Surround
|
||||
* LFE Low Frequency Effects
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
CUBEB_LAYOUT_UNDEFINED, // Indicate the speaker's layout is undefined.
|
||||
CUBEB_LAYOUT_DUAL_MONO,
|
||||
CUBEB_LAYOUT_DUAL_MONO_LFE,
|
||||
CUBEB_LAYOUT_MONO,
|
||||
CUBEB_LAYOUT_MONO_LFE,
|
||||
CUBEB_LAYOUT_STEREO,
|
||||
CUBEB_LAYOUT_STEREO_LFE,
|
||||
CUBEB_LAYOUT_3F,
|
||||
CUBEB_LAYOUT_3F_LFE,
|
||||
CUBEB_LAYOUT_2F1,
|
||||
CUBEB_LAYOUT_2F1_LFE,
|
||||
CUBEB_LAYOUT_3F1,
|
||||
CUBEB_LAYOUT_3F1_LFE,
|
||||
CUBEB_LAYOUT_2F2,
|
||||
CUBEB_LAYOUT_2F2_LFE,
|
||||
CUBEB_LAYOUT_3F2,
|
||||
CUBEB_LAYOUT_3F2_LFE,
|
||||
CUBEB_LAYOUT_3F3R_LFE,
|
||||
CUBEB_LAYOUT_3F4_LFE,
|
||||
CUBEB_LAYOUT_MAX
|
||||
} cubeb_channel_layout;
|
||||
|
||||
/** Stream format initialization parameters. */
|
||||
typedef struct {
|
||||
cubeb_sample_format format; /**< Requested sample format. One of
|
||||
#cubeb_sample_format. */
|
||||
unsigned int rate; /**< Requested sample rate. Valid range is [1000, 192000]. */
|
||||
unsigned int channels; /**< Requested channel count. Valid range is [1, 8]. */
|
||||
cubeb_sample_format format; /**< Requested sample format. One of
|
||||
#cubeb_sample_format. */
|
||||
unsigned int rate; /**< Requested sample rate. Valid range is [1000, 192000]. */
|
||||
unsigned int channels; /**< Requested channel count. Valid range is [1, 8]. */
|
||||
cubeb_channel_layout layout; /**< Requested channel layout. This must be consistent with the provided channels. */
|
||||
#if defined(__ANDROID__)
|
||||
cubeb_stream_type stream_type; /**< Used to map Android audio stream types */
|
||||
#endif
|
||||
|
@ -376,7 +435,7 @@ CUBEB_EXPORT int cubeb_get_max_channel_count(cubeb * context, uint32_t * max_cha
|
|||
|
||||
/** Get the minimal latency value, in frames, that is guaranteed to work
|
||||
when creating a stream for the specified sample rate. This is platform,
|
||||
hardware and backend dependant.
|
||||
hardware and backend dependent.
|
||||
@param context A pointer to the cubeb context.
|
||||
@param params On some backends, the minimum achievable latency depends on
|
||||
the characteristics of the stream.
|
||||
|
@ -390,7 +449,7 @@ CUBEB_EXPORT int cubeb_get_min_latency(cubeb * context,
|
|||
uint32_t * latency_frames);
|
||||
|
||||
/** Get the preferred sample rate for this backend: this is hardware and
|
||||
platform dependant, and can avoid resampling, and/or trigger fastpaths.
|
||||
platform dependent, and can avoid resampling, and/or trigger fastpaths.
|
||||
@param context A pointer to the cubeb context.
|
||||
@param rate The samplerate (in Hz) the current configuration prefers.
|
||||
@retval CUBEB_OK
|
||||
|
@ -398,6 +457,15 @@ CUBEB_EXPORT int cubeb_get_min_latency(cubeb * context,
|
|||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
CUBEB_EXPORT int cubeb_get_preferred_sample_rate(cubeb * context, uint32_t * rate);
|
||||
|
||||
/** Get the preferred layout for this backend: this is hardware and
|
||||
platform dependent.
|
||||
@param context A pointer to the cubeb context.
|
||||
@param layout The layout of the current speaker configuration.
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
CUBEB_EXPORT int cubeb_get_preferred_channel_layout(cubeb * context, cubeb_channel_layout * layout);
|
||||
|
||||
/** Destroy an application context. This must be called after all stream have
|
||||
* been destroyed.
|
||||
@param context A pointer to the cubeb context.*/
|
||||
|
|
|
@ -35,6 +35,14 @@ void cubeb_crash() CLANG_ANALYZER_NORETURN;
|
|||
}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char const * name;
|
||||
unsigned int const channels;
|
||||
cubeb_channel_layout const layout;
|
||||
} cubeb_layout_map;
|
||||
|
||||
extern cubeb_layout_map const CUBEB_CHANNEL_LAYOUT_MAPS[CUBEB_LAYOUT_MAX];
|
||||
|
||||
struct cubeb_ops {
|
||||
int (* init)(cubeb ** context, char const * context_name);
|
||||
char const * (* get_backend_id)(cubeb * context);
|
||||
|
@ -43,6 +51,7 @@ struct cubeb_ops {
|
|||
cubeb_stream_params params,
|
||||
uint32_t * latency_ms);
|
||||
int (* get_preferred_sample_rate)(cubeb * context, uint32_t * rate);
|
||||
int (* get_preferred_channel_layout)(cubeb * context, cubeb_channel_layout * layout);
|
||||
int (* enumerate_devices)(cubeb * context, cubeb_device_type type,
|
||||
cubeb_device_collection ** collection);
|
||||
void (* destroy)(cubeb * context);
|
||||
|
|
|
@ -55,7 +55,6 @@ int audiotrack_init(cubeb ** context, char const * context_name);
|
|||
int kai_init(cubeb ** context, char const * context_name);
|
||||
#endif
|
||||
|
||||
|
||||
static int
|
||||
validate_stream_params(cubeb_stream_params * input_stream_params,
|
||||
cubeb_stream_params * output_stream_params)
|
||||
|
@ -96,8 +95,6 @@ validate_stream_params(cubeb_stream_params * input_stream_params,
|
|||
return CUBEB_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
validate_latency(int latency)
|
||||
{
|
||||
|
@ -218,6 +215,20 @@ cubeb_get_preferred_sample_rate(cubeb * context, uint32_t * rate)
|
|||
return context->ops->get_preferred_sample_rate(context, rate);
|
||||
}
|
||||
|
||||
int
|
||||
cubeb_get_preferred_channel_layout(cubeb * context, cubeb_channel_layout * layout)
|
||||
{
|
||||
if (!context || !layout) {
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!context->ops->get_preferred_channel_layout) {
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return context->ops->get_preferred_channel_layout(context, layout);
|
||||
}
|
||||
|
||||
void
|
||||
cubeb_destroy(cubeb * context)
|
||||
{
|
||||
|
@ -565,4 +576,3 @@ cubeb_crash()
|
|||
abort();
|
||||
*((volatile int *) NULL) = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ struct cubeb_stream {
|
|||
cubeb_data_callback data_callback;
|
||||
cubeb_state_callback state_callback;
|
||||
void * user_ptr;
|
||||
snd_pcm_uframes_t write_position;
|
||||
snd_pcm_uframes_t stream_position;
|
||||
snd_pcm_uframes_t last_position;
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
cubeb_stream_params params;
|
||||
|
@ -107,6 +107,12 @@ struct cubeb_stream {
|
|||
being logically active and playing. */
|
||||
struct timeval last_activity;
|
||||
float volume;
|
||||
|
||||
char * buffer;
|
||||
snd_pcm_uframes_t bufframes;
|
||||
snd_pcm_stream_t stream_type;
|
||||
|
||||
struct cubeb_stream * other_stream;
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -234,6 +240,14 @@ set_timeout(struct timeval * timeout, unsigned int ms)
|
|||
timeout->tv_usec += (ms % 1000) * 1000;
|
||||
}
|
||||
|
||||
static void
|
||||
stream_buffer_decrement(cubeb_stream * stm, long count)
|
||||
{
|
||||
char * bufremains = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, count);
|
||||
memmove(stm->buffer, bufremains, snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes - count));
|
||||
stm->bufframes -= count;
|
||||
}
|
||||
|
||||
static void
|
||||
alsa_set_stream_state(cubeb_stream * stm, enum stream_state state)
|
||||
{
|
||||
|
@ -249,92 +263,173 @@ alsa_set_stream_state(cubeb_stream * stm, enum stream_state state)
|
|||
}
|
||||
|
||||
static enum stream_state
|
||||
alsa_refill_stream(cubeb_stream * stm)
|
||||
alsa_process_stream(cubeb_stream * stm)
|
||||
{
|
||||
unsigned short revents;
|
||||
snd_pcm_sframes_t avail;
|
||||
long got;
|
||||
void * p;
|
||||
int draining;
|
||||
|
||||
draining = 0;
|
||||
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
|
||||
/* Call _poll_descriptors_revents() even if we don't use it
|
||||
to let underlying plugins clear null events. Otherwise poll()
|
||||
may wake up again and again, producing unnecessary CPU usage. */
|
||||
snd_pcm_poll_descriptors_revents(stm->pcm, stm->fds, stm->nfds, &revents);
|
||||
|
||||
avail = snd_pcm_avail_update(stm->pcm);
|
||||
if (avail < 0) {
|
||||
snd_pcm_recover(stm->pcm, avail, 1);
|
||||
avail = snd_pcm_avail_update(stm->pcm);
|
||||
}
|
||||
|
||||
/* Failed to recover from an xrun, this stream must be broken. */
|
||||
if (avail < 0) {
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* This should never happen. */
|
||||
if ((unsigned int) avail > stm->buffer_size) {
|
||||
avail = stm->buffer_size;
|
||||
}
|
||||
|
||||
/* poll(2) claims this stream is active, so there should be some space
|
||||
available to write. If avail is still zero here, the stream must be in
|
||||
a funky state, bail and wait for another wakeup. */
|
||||
/* Got null event? Bail and wait for another wakeup. */
|
||||
if (avail == 0) {
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
return RUNNING;
|
||||
}
|
||||
|
||||
p = calloc(1, snd_pcm_frames_to_bytes(stm->pcm, avail));
|
||||
assert(p);
|
||||
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
got = stm->data_callback(stm, stm->user_ptr, NULL, p, avail);
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
if (got < 0) {
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
|
||||
free(p);
|
||||
return ERROR;
|
||||
/* This could happen if we were suspended with SIGSTOP/Ctrl+Z for a long time. */
|
||||
if ((unsigned int) avail > stm->buffer_size) {
|
||||
avail = stm->buffer_size;
|
||||
}
|
||||
if (got > 0) {
|
||||
|
||||
/* Capture: Read available frames */
|
||||
if (stm->stream_type == SND_PCM_STREAM_CAPTURE && avail > 0) {
|
||||
snd_pcm_sframes_t got;
|
||||
|
||||
if (avail + stm->bufframes > stm->buffer_size) {
|
||||
/* Buffer overflow. Skip and overwrite with new data. */
|
||||
stm->bufframes = 0;
|
||||
// TODO: should it be marked as DRAINING?
|
||||
}
|
||||
|
||||
got = snd_pcm_readi(stm->pcm, stm->buffer+stm->bufframes, avail);
|
||||
|
||||
if (got < 0) {
|
||||
avail = got; // the error handler below will recover us
|
||||
} else {
|
||||
stm->bufframes += got;
|
||||
stm->stream_position += got;
|
||||
|
||||
gettimeofday(&stm->last_activity, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Capture: Pass read frames to callback function */
|
||||
if (stm->stream_type == SND_PCM_STREAM_CAPTURE && stm->bufframes > 0 &&
|
||||
(!stm->other_stream || stm->other_stream->bufframes < stm->other_stream->buffer_size)) {
|
||||
long wrote = stm->bufframes;
|
||||
struct cubeb_stream * mainstm = stm->other_stream ? stm->other_stream : stm;
|
||||
void * other_buffer = stm->other_stream ? stm->other_stream->buffer + stm->other_stream->bufframes : NULL;
|
||||
|
||||
/* Correct write size to the other stream available space */
|
||||
if (stm->other_stream && wrote > stm->other_stream->buffer_size - stm->other_stream->bufframes) {
|
||||
wrote = stm->other_stream->buffer_size - stm->other_stream->bufframes;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
wrote = stm->data_callback(mainstm, stm->user_ptr, stm->buffer, other_buffer, wrote);
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
|
||||
if (wrote < 0) {
|
||||
avail = wrote; // the error handler below will recover us
|
||||
} else {
|
||||
stream_buffer_decrement(stm, wrote);
|
||||
|
||||
if (stm->other_stream) {
|
||||
stm->other_stream->bufframes += wrote;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Playback: Don't have enough data? Let's ask for more. */
|
||||
if (stm->stream_type == SND_PCM_STREAM_PLAYBACK && avail > stm->bufframes &&
|
||||
(!stm->other_stream || stm->other_stream->bufframes > 0)) {
|
||||
long got = avail - stm->bufframes;
|
||||
void * other_buffer = stm->other_stream ? stm->other_stream->buffer : NULL;
|
||||
char * buftail = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes);
|
||||
|
||||
/* Correct read size to the other stream available frames */
|
||||
if (stm->other_stream && got > stm->other_stream->bufframes) {
|
||||
got = stm->other_stream->bufframes;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
got = stm->data_callback(stm, stm->user_ptr, other_buffer, buftail, got);
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
|
||||
if (got < 0) {
|
||||
avail = got; // the error handler below will recover us
|
||||
} else {
|
||||
stm->bufframes += got;
|
||||
|
||||
if (stm->other_stream) {
|
||||
stream_buffer_decrement(stm->other_stream, got);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Playback: Still don't have enough data? Add some silence. */
|
||||
if (stm->stream_type == SND_PCM_STREAM_PLAYBACK && avail > stm->bufframes) {
|
||||
long drain_frames = avail - stm->bufframes;
|
||||
double drain_time = (double) drain_frames / stm->params.rate;
|
||||
|
||||
char * buftail = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes);
|
||||
memset(buftail, 0, snd_pcm_frames_to_bytes(stm->pcm, drain_frames));
|
||||
stm->bufframes = avail;
|
||||
|
||||
/* Mark as draining, unless we're waiting for capture */
|
||||
if (!stm->other_stream || stm->other_stream->bufframes > 0) {
|
||||
set_timeout(&stm->drain_timeout, drain_time * 1000);
|
||||
|
||||
draining = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Playback: Have enough data and no errors. Let's write it out. */
|
||||
if (stm->stream_type == SND_PCM_STREAM_PLAYBACK && avail > 0) {
|
||||
snd_pcm_sframes_t wrote;
|
||||
|
||||
if (stm->params.format == CUBEB_SAMPLE_FLOAT32NE) {
|
||||
float * b = (float *) p;
|
||||
for (uint32_t i = 0; i < got * stm->params.channels; i++) {
|
||||
float * b = (float *) stm->buffer;
|
||||
for (uint32_t i = 0; i < avail * stm->params.channels; i++) {
|
||||
b[i] *= stm->volume;
|
||||
}
|
||||
} else {
|
||||
short * b = (short *) p;
|
||||
for (uint32_t i = 0; i < got * stm->params.channels; i++) {
|
||||
short * b = (short *) stm->buffer;
|
||||
for (uint32_t i = 0; i < avail * stm->params.channels; i++) {
|
||||
b[i] *= stm->volume;
|
||||
}
|
||||
}
|
||||
wrote = snd_pcm_writei(stm->pcm, p, got);
|
||||
|
||||
wrote = snd_pcm_writei(stm->pcm, stm->buffer, avail);
|
||||
if (wrote < 0) {
|
||||
snd_pcm_recover(stm->pcm, wrote, 1);
|
||||
wrote = snd_pcm_writei(stm->pcm, p, got);
|
||||
avail = wrote; // the error handler below will recover us
|
||||
} else {
|
||||
stream_buffer_decrement(stm, wrote);
|
||||
|
||||
stm->stream_position += wrote;
|
||||
gettimeofday(&stm->last_activity, NULL);
|
||||
}
|
||||
assert(wrote >= 0 && wrote == got);
|
||||
stm->write_position += wrote;
|
||||
gettimeofday(&stm->last_activity, NULL);
|
||||
}
|
||||
if (got != avail) {
|
||||
long buffer_fill = stm->buffer_size - (avail - got);
|
||||
double buffer_time = (double) buffer_fill / stm->params.rate;
|
||||
|
||||
/* Fill the remaining buffer with silence to guarantee one full period
|
||||
has been written. */
|
||||
snd_pcm_writei(stm->pcm, (char *) p + got, avail - got);
|
||||
|
||||
set_timeout(&stm->drain_timeout, buffer_time * 1000);
|
||||
|
||||
draining = 1;
|
||||
}
|
||||
|
||||
free(p);
|
||||
/* Got some error? Let's try to recover the stream. */
|
||||
if (avail < 0) {
|
||||
avail = snd_pcm_recover(stm->pcm, avail, 0);
|
||||
|
||||
/* Capture pcm must be started after initial setup/recover */
|
||||
if (avail >= 0 &&
|
||||
stm->stream_type == SND_PCM_STREAM_CAPTURE &&
|
||||
snd_pcm_state(stm->pcm) == SND_PCM_STATE_PREPARED) {
|
||||
avail = snd_pcm_start(stm->pcm);
|
||||
}
|
||||
}
|
||||
|
||||
/* Failed to recover, this stream must be broken. */
|
||||
if (avail < 0) {
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
return draining ? DRAINING : RUNNING;
|
||||
}
|
||||
|
@ -390,7 +485,7 @@ alsa_run(cubeb * ctx)
|
|||
if (stm && stm->state == RUNNING && stm->fds && any_revents(stm->fds, stm->nfds)) {
|
||||
alsa_set_stream_state(stm, PROCESSING);
|
||||
pthread_mutex_unlock(&ctx->mutex);
|
||||
state = alsa_refill_stream(stm);
|
||||
state = alsa_process_stream(stm);
|
||||
pthread_mutex_lock(&ctx->mutex);
|
||||
alsa_set_stream_state(stm, state);
|
||||
}
|
||||
|
@ -576,15 +671,15 @@ init_local_config_with_workaround(char const * pcm_name)
|
|||
}
|
||||
|
||||
static int
|
||||
alsa_locked_pcm_open(snd_pcm_t ** pcm, snd_pcm_stream_t stream, snd_config_t * local_config)
|
||||
alsa_locked_pcm_open(snd_pcm_t ** pcm, char const * pcm_name, snd_pcm_stream_t stream, snd_config_t * local_config)
|
||||
{
|
||||
int r;
|
||||
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
if (local_config) {
|
||||
r = snd_pcm_open_lconf(pcm, CUBEB_ALSA_PCM_NAME, stream, SND_PCM_NONBLOCK, local_config);
|
||||
r = snd_pcm_open_lconf(pcm, pcm_name, stream, SND_PCM_NONBLOCK, local_config);
|
||||
} else {
|
||||
r = snd_pcm_open(pcm, CUBEB_ALSA_PCM_NAME, stream, SND_PCM_NONBLOCK);
|
||||
r = snd_pcm_open(pcm, pcm_name, stream, SND_PCM_NONBLOCK);
|
||||
}
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
|
||||
|
@ -707,7 +802,7 @@ alsa_init(cubeb ** context, char const * context_name)
|
|||
|
||||
/* Open a dummy PCM to force the configuration space to be evaluated so that
|
||||
init_local_config_with_workaround can find and modify the default node. */
|
||||
r = alsa_locked_pcm_open(&dummy, SND_PCM_STREAM_PLAYBACK, NULL);
|
||||
r = alsa_locked_pcm_open(&dummy, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, NULL);
|
||||
if (r >= 0) {
|
||||
alsa_locked_pcm_close(dummy);
|
||||
}
|
||||
|
@ -717,7 +812,7 @@ alsa_init(cubeb ** context, char const * context_name)
|
|||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
if (ctx->local_config) {
|
||||
ctx->is_pa = 1;
|
||||
r = alsa_locked_pcm_open(&dummy, SND_PCM_STREAM_PLAYBACK, ctx->local_config);
|
||||
r = alsa_locked_pcm_open(&dummy, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, ctx->local_config);
|
||||
/* If we got a local_config, we found a PA PCM. If opening a PCM with that
|
||||
config fails with EINVAL, the PA PCM is too old for this workaround. */
|
||||
if (r == -EINVAL) {
|
||||
|
@ -774,14 +869,14 @@ alsa_destroy(cubeb * ctx)
|
|||
static void alsa_stream_destroy(cubeb_stream * stm);
|
||||
|
||||
static int
|
||||
alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
|
||||
cubeb_devid input_device,
|
||||
cubeb_stream_params * input_stream_params,
|
||||
cubeb_devid output_device,
|
||||
cubeb_stream_params * output_stream_params,
|
||||
unsigned int latency_frames,
|
||||
cubeb_data_callback data_callback, cubeb_state_callback state_callback,
|
||||
void * user_ptr)
|
||||
alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
|
||||
snd_pcm_stream_t stream_type,
|
||||
cubeb_devid deviceid,
|
||||
cubeb_stream_params * stream_params,
|
||||
unsigned int latency_frames,
|
||||
cubeb_data_callback data_callback,
|
||||
cubeb_state_callback state_callback,
|
||||
void * user_ptr)
|
||||
{
|
||||
(void)stream_name;
|
||||
cubeb_stream * stm;
|
||||
|
@ -789,23 +884,13 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
|
|||
snd_pcm_format_t format;
|
||||
snd_pcm_uframes_t period_size;
|
||||
int latency_us = 0;
|
||||
|
||||
char const * pcm_name = deviceid ? (char const *) deviceid : CUBEB_ALSA_PCM_NAME;
|
||||
|
||||
assert(ctx && stream);
|
||||
|
||||
if (input_stream_params) {
|
||||
/* Capture support not yet implemented. */
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (input_device || output_device) {
|
||||
/* Device selection not yet implemented. */
|
||||
return CUBEB_ERROR_DEVICE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
*stream = NULL;
|
||||
|
||||
switch (output_stream_params->format) {
|
||||
switch (stream_params->format) {
|
||||
case CUBEB_SAMPLE_S16LE:
|
||||
format = SND_PCM_FORMAT_S16_LE;
|
||||
break;
|
||||
|
@ -837,14 +922,18 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
|
|||
stm->data_callback = data_callback;
|
||||
stm->state_callback = state_callback;
|
||||
stm->user_ptr = user_ptr;
|
||||
stm->params = *output_stream_params;
|
||||
stm->params = *stream_params;
|
||||
stm->state = INACTIVE;
|
||||
stm->volume = 1.0;
|
||||
stm->buffer = NULL;
|
||||
stm->bufframes = 0;
|
||||
stm->stream_type = stream_type;
|
||||
stm->other_stream = NULL;
|
||||
|
||||
r = pthread_mutex_init(&stm->mutex, NULL);
|
||||
assert(r == 0);
|
||||
|
||||
r = alsa_locked_pcm_open(&stm->pcm, SND_PCM_STREAM_PLAYBACK, ctx->local_config);
|
||||
r = alsa_locked_pcm_open(&stm->pcm, pcm_name, stm->stream_type, ctx->local_config);
|
||||
if (r < 0) {
|
||||
alsa_stream_destroy(stm);
|
||||
return CUBEB_ERROR;
|
||||
|
@ -874,6 +963,11 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
|
|||
r = snd_pcm_get_params(stm->pcm, &stm->buffer_size, &period_size);
|
||||
assert(r == 0);
|
||||
|
||||
/* Double internal buffer size to have enough space when waiting for the other side of duplex connection */
|
||||
stm->buffer_size *= 2;
|
||||
stm->buffer = calloc(1, snd_pcm_frames_to_bytes(stm->pcm, stm->buffer_size));
|
||||
assert(stm->buffer);
|
||||
|
||||
stm->nfds = snd_pcm_poll_descriptors_count(stm->pcm);
|
||||
assert(stm->nfds > 0);
|
||||
|
||||
|
@ -895,6 +989,45 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
|
|||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
|
||||
cubeb_devid input_device,
|
||||
cubeb_stream_params * input_stream_params,
|
||||
cubeb_devid output_device,
|
||||
cubeb_stream_params * output_stream_params,
|
||||
unsigned int latency_frames,
|
||||
cubeb_data_callback data_callback, cubeb_state_callback state_callback,
|
||||
void * user_ptr)
|
||||
{
|
||||
int result = CUBEB_OK;
|
||||
cubeb_stream * instm = NULL, * outstm = NULL;
|
||||
|
||||
if (result == CUBEB_OK && input_stream_params) {
|
||||
result = alsa_stream_init_single(ctx, &instm, stream_name, SND_PCM_STREAM_CAPTURE,
|
||||
input_device, input_stream_params, latency_frames,
|
||||
data_callback, state_callback, user_ptr);
|
||||
}
|
||||
|
||||
if (result == CUBEB_OK && output_stream_params) {
|
||||
result = alsa_stream_init_single(ctx, &outstm, stream_name, SND_PCM_STREAM_PLAYBACK,
|
||||
output_device, output_stream_params, latency_frames,
|
||||
data_callback, state_callback, user_ptr);
|
||||
}
|
||||
|
||||
if (result == CUBEB_OK && input_stream_params && output_stream_params) {
|
||||
instm->other_stream = outstm;
|
||||
outstm->other_stream = instm;
|
||||
}
|
||||
|
||||
if (result != CUBEB_OK && instm) {
|
||||
alsa_stream_destroy(instm);
|
||||
}
|
||||
|
||||
*stream = outstm ? outstm : instm;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
alsa_stream_destroy(cubeb_stream * stm)
|
||||
{
|
||||
|
@ -907,6 +1040,11 @@ alsa_stream_destroy(cubeb_stream * stm)
|
|||
|
||||
ctx = stm->context;
|
||||
|
||||
if (stm->other_stream) {
|
||||
stm->other_stream->other_stream = NULL; // to stop infinite recursion
|
||||
alsa_stream_destroy(stm->other_stream);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
if (stm->pcm) {
|
||||
if (stm->state == DRAINING) {
|
||||
|
@ -929,6 +1067,8 @@ alsa_stream_destroy(cubeb_stream * stm)
|
|||
ctx->active_streams -= 1;
|
||||
pthread_mutex_unlock(&ctx->mutex);
|
||||
|
||||
free(stm->buffer);
|
||||
|
||||
free(stm);
|
||||
}
|
||||
|
||||
|
@ -952,6 +1092,8 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
|
|||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
assert(stm);
|
||||
|
||||
r = snd_pcm_hw_params_any(stm->pcm, hw_params);
|
||||
if (r < 0) {
|
||||
return CUBEB_ERROR;
|
||||
|
@ -1029,7 +1171,18 @@ alsa_stream_start(cubeb_stream * stm)
|
|||
assert(stm);
|
||||
ctx = stm->context;
|
||||
|
||||
if (stm->stream_type == SND_PCM_STREAM_PLAYBACK && stm->other_stream) {
|
||||
int r = alsa_stream_start(stm->other_stream);
|
||||
if (r != CUBEB_OK)
|
||||
return r;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
/* Capture pcm must be started after initial setup/recover */
|
||||
if (stm->stream_type == SND_PCM_STREAM_CAPTURE &&
|
||||
snd_pcm_state(stm->pcm) == SND_PCM_STATE_PREPARED) {
|
||||
snd_pcm_start(stm->pcm);
|
||||
}
|
||||
snd_pcm_pause(stm->pcm, 0);
|
||||
gettimeofday(&stm->last_activity, NULL);
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
|
@ -1054,6 +1207,12 @@ alsa_stream_stop(cubeb_stream * stm)
|
|||
assert(stm);
|
||||
ctx = stm->context;
|
||||
|
||||
if (stm->stream_type == SND_PCM_STREAM_PLAYBACK && stm->other_stream) {
|
||||
int r = alsa_stream_stop(stm->other_stream);
|
||||
if (r != CUBEB_OK)
|
||||
return r;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&ctx->mutex);
|
||||
while (stm->state == PROCESSING) {
|
||||
r = pthread_cond_wait(&stm->cond, &ctx->mutex);
|
||||
|
@ -1090,8 +1249,8 @@ alsa_stream_get_position(cubeb_stream * stm, uint64_t * position)
|
|||
assert(delay >= 0);
|
||||
|
||||
*position = 0;
|
||||
if (stm->write_position >= (snd_pcm_uframes_t) delay) {
|
||||
*position = stm->write_position - delay;
|
||||
if (stm->stream_position >= (snd_pcm_uframes_t) delay) {
|
||||
*position = stm->stream_position - delay;
|
||||
}
|
||||
|
||||
stm->last_position = *position;
|
||||
|
@ -1126,13 +1285,63 @@ alsa_stream_set_volume(cubeb_stream * stm, float volume)
|
|||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
alsa_enumerate_devices(cubeb * context, cubeb_device_type type,
|
||||
cubeb_device_collection ** collection)
|
||||
{
|
||||
if (!context)
|
||||
return CUBEB_ERROR;
|
||||
|
||||
uint32_t rate, max_channels;
|
||||
int r;
|
||||
|
||||
r = alsa_get_preferred_sample_rate(context, &rate);
|
||||
if (r != CUBEB_OK) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
r = alsa_get_max_channel_count(context, &max_channels);
|
||||
if (r != CUBEB_OK) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
*collection = (cubeb_device_collection *) calloc(1, sizeof(cubeb_device_collection) + 1*sizeof(cubeb_device_info *));
|
||||
assert(*collection);
|
||||
|
||||
char const * a_name = "default";
|
||||
(*collection)->device[0] = (cubeb_device_info *) calloc(1, sizeof(cubeb_device_info));
|
||||
assert((*collection)->device[0]);
|
||||
|
||||
(*collection)->device[0]->device_id = strdup(a_name);
|
||||
(*collection)->device[0]->devid = (*collection)->device[0]->device_id;
|
||||
(*collection)->device[0]->friendly_name = strdup(a_name);
|
||||
(*collection)->device[0]->group_id = strdup(a_name);
|
||||
(*collection)->device[0]->vendor_name = strdup(a_name);
|
||||
(*collection)->device[0]->type = type;
|
||||
(*collection)->device[0]->state = CUBEB_DEVICE_STATE_ENABLED;
|
||||
(*collection)->device[0]->preferred = CUBEB_DEVICE_PREF_ALL;
|
||||
(*collection)->device[0]->format = CUBEB_DEVICE_FMT_S16NE;
|
||||
(*collection)->device[0]->default_format = CUBEB_DEVICE_FMT_S16NE;
|
||||
(*collection)->device[0]->max_channels = max_channels;
|
||||
(*collection)->device[0]->min_rate = rate;
|
||||
(*collection)->device[0]->max_rate = rate;
|
||||
(*collection)->device[0]->default_rate = rate;
|
||||
(*collection)->device[0]->latency_lo = 0;
|
||||
(*collection)->device[0]->latency_hi = 0;
|
||||
|
||||
(*collection)->count = 1;
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static struct cubeb_ops const alsa_ops = {
|
||||
.init = alsa_init,
|
||||
.get_backend_id = alsa_get_backend_id,
|
||||
.get_max_channel_count = alsa_get_max_channel_count,
|
||||
.get_min_latency = alsa_get_min_latency,
|
||||
.get_preferred_sample_rate = alsa_get_preferred_sample_rate,
|
||||
.enumerate_devices = NULL,
|
||||
.get_preferred_channel_layout = NULL,
|
||||
.enumerate_devices = alsa_enumerate_devices,
|
||||
.destroy = alsa_destroy,
|
||||
.stream_init = alsa_stream_init,
|
||||
.stream_destroy = alsa_stream_destroy,
|
||||
|
|
|
@ -421,6 +421,7 @@ static struct cubeb_ops const audiotrack_ops = {
|
|||
.get_max_channel_count = audiotrack_get_max_channel_count,
|
||||
.get_min_latency = audiotrack_get_min_latency,
|
||||
.get_preferred_sample_rate = audiotrack_get_preferred_sample_rate,
|
||||
.get_preferred_channel_layout = NULL,
|
||||
.enumerate_devices = NULL,
|
||||
.destroy = audiotrack_destroy,
|
||||
.stream_init = audiotrack_stream_init,
|
||||
|
|
|
@ -40,9 +40,11 @@ typedef UInt32 AudioFormatFlags;
|
|||
#define AU_OUT_BUS 0
|
||||
#define AU_IN_BUS 1
|
||||
|
||||
#define PRINT_ERROR_CODE(str, r) do { \
|
||||
LOG("System call failed: %s (rv: %d)", str, r); \
|
||||
} while(0)
|
||||
#define PRINT_ERROR_CODE(str, r) do { \
|
||||
LOG("System call failed: %s (rv: %d)", str, (int) r); \
|
||||
} while(0)
|
||||
|
||||
const char * DISPATCH_QUEUE_LABEL = "org.mozilla.cubeb";
|
||||
|
||||
/* Testing empirically, some headsets report a minimal latency that is very
|
||||
* low, but this does not work in practice. Lie and say the minimum is 256
|
||||
|
@ -52,8 +54,8 @@ const uint32_t SAFE_MAX_LATENCY_FRAMES = 512;
|
|||
|
||||
void audiounit_stream_stop_internal(cubeb_stream * stm);
|
||||
void audiounit_stream_start_internal(cubeb_stream * stm);
|
||||
static void close_audiounit_stream(cubeb_stream * stm);
|
||||
static int setup_audiounit_stream(cubeb_stream * stm);
|
||||
static void audiounit_close_stream(cubeb_stream *stm);
|
||||
static int audiounit_setup_stream(cubeb_stream *stm);
|
||||
|
||||
extern cubeb_ops const audiounit_ops;
|
||||
|
||||
|
@ -61,11 +63,14 @@ struct cubeb {
|
|||
cubeb_ops const * ops = &audiounit_ops;
|
||||
owned_critical_section mutex;
|
||||
std::atomic<int> active_streams{ 0 };
|
||||
uint32_t global_latency_frames = 0;
|
||||
cubeb_device_collection_changed_callback collection_changed_callback = nullptr;
|
||||
void * collection_changed_user_ptr = nullptr;
|
||||
/* Differentiate input from output devices. */
|
||||
cubeb_device_type collection_changed_devtype = CUBEB_DEVICE_TYPE_UNKNOWN;
|
||||
std::vector<AudioObjectID> devtype_device_array;
|
||||
// The queue is asynchronously deallocated once all references to it are released
|
||||
dispatch_queue_t serial_queue = dispatch_queue_create(DISPATCH_QUEUE_LABEL, DISPATCH_QUEUE_SERIAL);
|
||||
};
|
||||
|
||||
struct auto_array_wrapper {
|
||||
|
@ -133,8 +138,8 @@ struct cubeb_stream {
|
|||
cubeb_state_callback state_callback = nullptr;
|
||||
cubeb_device_changed_callback device_changed_callback = nullptr;
|
||||
/* Stream creation parameters */
|
||||
cubeb_stream_params input_stream_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0 };
|
||||
cubeb_stream_params output_stream_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0 };
|
||||
cubeb_stream_params input_stream_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0, CUBEB_LAYOUT_UNDEFINED };
|
||||
cubeb_stream_params output_stream_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0, CUBEB_LAYOUT_UNDEFINED };
|
||||
bool is_default_input;
|
||||
AudioDeviceID input_device = 0;
|
||||
AudioDeviceID output_device = 0;
|
||||
|
@ -177,6 +182,7 @@ struct cubeb_stream {
|
|||
std::atomic<int> output_callback_in_a_row{ 0 };
|
||||
/* This is true if a device change callback is currently running. */
|
||||
std::atomic<bool> switching_device{ false };
|
||||
std::atomic<bool> buffer_size_change_state{ false };
|
||||
};
|
||||
|
||||
bool has_input(cubeb_stream * stm)
|
||||
|
@ -227,6 +233,14 @@ audiotimestamp_to_latency(AudioTimeStamp const * tstamp, cubeb_stream * stream)
|
|||
return ((pres - now) * stream->output_desc.mSampleRate) / 1000000000LL;
|
||||
}
|
||||
|
||||
static void
|
||||
audiounit_set_global_latency(cubeb_stream * stm, uint32_t latency_frames)
|
||||
{
|
||||
stm->mutex.assert_current_thread_owns();
|
||||
assert(stm->context->active_streams == 1);
|
||||
stm->context->global_latency_frames = latency_frames;
|
||||
}
|
||||
|
||||
static void
|
||||
audiounit_make_silent(AudioBuffer * ioData)
|
||||
{
|
||||
|
@ -267,11 +281,12 @@ audiounit_render_input(cubeb_stream * stm,
|
|||
stm->input_linear_buffer->push(input_buffer_list.mBuffers[0].mData,
|
||||
input_frames * stm->input_desc.mChannelsPerFrame);
|
||||
|
||||
LOGV("(%p) input: buffers %d, size %d, channels %d, frames %d.",
|
||||
stm, input_buffer_list.mNumberBuffers,
|
||||
input_buffer_list.mBuffers[0].mDataByteSize,
|
||||
input_buffer_list.mBuffers[0].mNumberChannels,
|
||||
input_frames);
|
||||
LOGV("(%p) input: buffers %u, size %u, channels %u, frames %d.",
|
||||
stm,
|
||||
(unsigned int) input_buffer_list.mNumberBuffers,
|
||||
(unsigned int) input_buffer_list.mBuffers[0].mDataByteSize,
|
||||
(unsigned int) input_buffer_list.mBuffers[0].mNumberChannels,
|
||||
(unsigned int) input_frames);
|
||||
|
||||
/* Advance input frame counter. */
|
||||
assert(input_frames > 0);
|
||||
|
@ -289,7 +304,6 @@ audiounit_input_callback(void * user_ptr,
|
|||
AudioBufferList * /* bufs */)
|
||||
{
|
||||
cubeb_stream * stm = static_cast<cubeb_stream *>(user_ptr);
|
||||
long outframes;
|
||||
|
||||
assert(stm->input_unit != NULL);
|
||||
assert(AU_IN_BUS == bus);
|
||||
|
@ -323,15 +337,15 @@ audiounit_input_callback(void * user_ptr,
|
|||
Resampler will deliver input buffer in the correct rate. */
|
||||
assert(input_frames <= stm->input_linear_buffer->length() / stm->input_desc.mChannelsPerFrame);
|
||||
long total_input_frames = stm->input_linear_buffer->length() / stm->input_desc.mChannelsPerFrame;
|
||||
outframes = cubeb_resampler_fill(stm->resampler.get(),
|
||||
stm->input_linear_buffer->data(),
|
||||
&total_input_frames,
|
||||
NULL,
|
||||
0);
|
||||
long outframes = cubeb_resampler_fill(stm->resampler.get(),
|
||||
stm->input_linear_buffer->data(),
|
||||
&total_input_frames,
|
||||
NULL,
|
||||
0);
|
||||
// Reset input buffer
|
||||
stm->input_linear_buffer->clear();
|
||||
|
||||
if (outframes < 0 || outframes != input_frames) {
|
||||
if (outframes < 0 || (UInt32) outframes != input_frames) {
|
||||
stm->shutdown = true;
|
||||
return noErr;
|
||||
}
|
||||
|
@ -375,12 +389,14 @@ audiounit_output_callback(void * user_ptr,
|
|||
|
||||
stm->output_callback_in_a_row++;
|
||||
|
||||
LOGV("(%p) output: buffers %d, size %d, channels %d, frames %d.",
|
||||
stm, outBufferList->mNumberBuffers,
|
||||
outBufferList->mBuffers[0].mDataByteSize,
|
||||
outBufferList->mBuffers[0].mNumberChannels, output_frames);
|
||||
LOGV("(%p) output: buffers %u, size %u, channels %u, frames %u.",
|
||||
stm,
|
||||
(unsigned int) outBufferList->mNumberBuffers,
|
||||
(unsigned int) outBufferList->mBuffers[0].mDataByteSize,
|
||||
(unsigned int) outBufferList->mBuffers[0].mNumberChannels,
|
||||
(unsigned int) output_frames);
|
||||
|
||||
long outframes = 0, input_frames = 0;
|
||||
long input_frames = 0;
|
||||
void * output_buffer = NULL, * input_buffer = NULL;
|
||||
|
||||
if (stm->shutdown) {
|
||||
|
@ -419,11 +435,11 @@ audiounit_output_callback(void * user_ptr,
|
|||
}
|
||||
|
||||
/* Call user callback through resampler. */
|
||||
outframes = cubeb_resampler_fill(stm->resampler.get(),
|
||||
input_buffer,
|
||||
input_buffer ? &input_frames : NULL,
|
||||
output_buffer,
|
||||
output_frames);
|
||||
long outframes = cubeb_resampler_fill(stm->resampler.get(),
|
||||
input_buffer,
|
||||
input_buffer ? &input_frames : NULL,
|
||||
output_buffer,
|
||||
output_frames);
|
||||
|
||||
if (input_buffer) {
|
||||
stm->input_linear_buffer->pop(input_frames * stm->input_desc.mChannelsPerFrame);
|
||||
|
@ -435,7 +451,7 @@ audiounit_output_callback(void * user_ptr,
|
|||
}
|
||||
|
||||
size_t outbpf = stm->output_desc.mBytesPerFrame;
|
||||
stm->draining = outframes < output_frames;
|
||||
stm->draining = (UInt32) outframes < output_frames;
|
||||
stm->frames_played = stm->frames_queued;
|
||||
stm->frames_queued += outframes;
|
||||
|
||||
|
@ -533,37 +549,62 @@ audiounit_get_input_device_id(AudioDeviceID * device_id)
|
|||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
audiounit_reinit_stream(cubeb_stream * stm, bool is_started)
|
||||
{
|
||||
if (is_started) {
|
||||
audiounit_stream_stop_internal(stm);
|
||||
}
|
||||
|
||||
{
|
||||
auto_lock lock(stm->mutex);
|
||||
|
||||
audiounit_close_stream(stm);
|
||||
|
||||
if (audiounit_setup_stream(stm) != CUBEB_OK) {
|
||||
LOG("(%p) Stream reinit failed.", stm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
// Reset input frames to force new stream pre-buffer
|
||||
// silence if needed, check `is_extra_input_needed()`
|
||||
stm->frames_read = 0;
|
||||
|
||||
// If the stream was running, start it again.
|
||||
if (is_started) {
|
||||
audiounit_stream_start_internal(stm);
|
||||
}
|
||||
}
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static OSStatus
|
||||
audiounit_property_listener_callback(AudioObjectID /* id */, UInt32 address_count,
|
||||
const AudioObjectPropertyAddress * addresses,
|
||||
void * user)
|
||||
{
|
||||
cubeb_stream * stm = (cubeb_stream*) user;
|
||||
int rv;
|
||||
bool was_running = false;
|
||||
|
||||
stm->switching_device = true;
|
||||
|
||||
// Note if the stream was running or not
|
||||
was_running = !stm->shutdown;
|
||||
bool was_running = !stm->shutdown;
|
||||
|
||||
LOG("(%p) Audio device changed, %d events.", stm, address_count);
|
||||
LOG("(%p) Audio device changed, %u events.", stm, (unsigned int) address_count);
|
||||
for (UInt32 i = 0; i < address_count; i++) {
|
||||
switch(addresses[i].mSelector) {
|
||||
case kAudioHardwarePropertyDefaultOutputDevice: {
|
||||
LOG("Event[%d] - mSelector == kAudioHardwarePropertyDefaultOutputDevice", i);
|
||||
LOG("Event[%u] - mSelector == kAudioHardwarePropertyDefaultOutputDevice", (unsigned int) i);
|
||||
// Allow restart to choose the new default
|
||||
stm->output_device = 0;
|
||||
}
|
||||
break;
|
||||
case kAudioHardwarePropertyDefaultInputDevice: {
|
||||
LOG("Event[%d] - mSelector == kAudioHardwarePropertyDefaultInputDevice", i);
|
||||
LOG("Event[%u] - mSelector == kAudioHardwarePropertyDefaultInputDevice", (unsigned int) i);
|
||||
// Allow restart to choose the new default
|
||||
stm->input_device = 0;
|
||||
}
|
||||
break;
|
||||
case kAudioDevicePropertyDeviceIsAlive: {
|
||||
LOG("Event[%d] - mSelector == kAudioDevicePropertyDeviceIsAlive", i);
|
||||
LOG("Event[%u] - mSelector == kAudioDevicePropertyDeviceIsAlive", (unsigned int) i);
|
||||
// If this is the default input device ignore the event,
|
||||
// kAudioHardwarePropertyDefaultInputDevice will take care of the switch
|
||||
if (stm->is_default_input) {
|
||||
|
@ -575,7 +616,7 @@ audiounit_property_listener_callback(AudioObjectID /* id */, UInt32 address_coun
|
|||
}
|
||||
break;
|
||||
case kAudioDevicePropertyDataSource:
|
||||
LOG("Event[%d] - mSelector == kAudioHardwarePropertyDataSource", i);
|
||||
LOG("Event[%u] - mSelector == kAudioHardwarePropertyDataSource", (unsigned int) i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -596,28 +637,15 @@ audiounit_property_listener_callback(AudioObjectID /* id */, UInt32 address_coun
|
|||
}
|
||||
}
|
||||
|
||||
// This means the callback won't be called again.
|
||||
audiounit_stream_stop_internal(stm);
|
||||
|
||||
{
|
||||
auto_lock lock(stm->mutex);
|
||||
close_audiounit_stream(stm);
|
||||
rv = setup_audiounit_stream(stm);
|
||||
if (rv != CUBEB_OK) {
|
||||
LOG("(%p) Could not reopen a stream after switching.", stm);
|
||||
// Use a new thread, through the queue, to avoid deadlock when calling
|
||||
// Get/SetProperties method from inside notify callback
|
||||
dispatch_async(stm->context->serial_queue, ^() {
|
||||
if (audiounit_reinit_stream(stm, was_running) != CUBEB_OK) {
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
|
||||
return noErr;
|
||||
LOG("(%p) Could not reopen the stream after switching.", stm);
|
||||
}
|
||||
|
||||
stm->frames_read = 0;
|
||||
|
||||
// If the stream was running, start it again.
|
||||
if (was_running) {
|
||||
audiounit_stream_start_internal(stm);
|
||||
}
|
||||
}
|
||||
|
||||
stm->switching_device = false;
|
||||
stm->switching_device = false;
|
||||
});
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
@ -1099,8 +1127,7 @@ audiounit_init_input_linear_buffer(cubeb_stream * stream, uint32_t capacity)
|
|||
}
|
||||
|
||||
static uint32_t
|
||||
audiounit_clamp_latency(cubeb_stream * stm,
|
||||
uint32_t latency_frames)
|
||||
audiounit_clamp_latency(cubeb_stream * stm, uint32_t latency_frames)
|
||||
{
|
||||
// For the 1st stream set anything within safe min-max
|
||||
assert(stm->context->active_streams > 0);
|
||||
|
@ -1163,16 +1190,364 @@ audiounit_clamp_latency(cubeb_stream * stm,
|
|||
SAFE_MIN_LATENCY_FRAMES);
|
||||
}
|
||||
|
||||
static int
|
||||
setup_audiounit_stream(cubeb_stream * stm)
|
||||
/*
|
||||
* Change buffer size is prone to deadlock thus we change it
|
||||
* following the steps:
|
||||
* - register a listener for the buffer size property
|
||||
* - change the property
|
||||
* - wait until the listener is executed
|
||||
* - property has changed, remove the listener
|
||||
* */
|
||||
static void
|
||||
buffer_size_changed_callback(void * inClientData,
|
||||
AudioUnit inUnit,
|
||||
AudioUnitPropertyID inPropertyID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement)
|
||||
{
|
||||
stm->mutex.assert_current_thread_owns();
|
||||
cubeb_stream * stm = (cubeb_stream *)inClientData;
|
||||
|
||||
int r;
|
||||
AudioUnit au = inUnit;
|
||||
AudioUnitScope au_scope = kAudioUnitScope_Input;
|
||||
AudioUnitElement au_element = inElement;
|
||||
const char * au_type = "output";
|
||||
|
||||
if (au == stm->input_unit) {
|
||||
au_scope = kAudioUnitScope_Output;
|
||||
au_type = "input";
|
||||
}
|
||||
|
||||
switch (inPropertyID) {
|
||||
|
||||
case kAudioDevicePropertyBufferFrameSize: {
|
||||
if (inScope != au_scope) {
|
||||
break;
|
||||
}
|
||||
UInt32 new_buffer_size;
|
||||
UInt32 outSize = sizeof(UInt32);
|
||||
OSStatus r = AudioUnitGetProperty(au,
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
au_scope,
|
||||
au_element,
|
||||
&new_buffer_size,
|
||||
&outSize);
|
||||
if (r != noErr) {
|
||||
LOG("(%p) Event: kAudioDevicePropertyBufferFrameSize: Cannot get current buffer size", stm);
|
||||
} else {
|
||||
LOG("(%p) Event: kAudioDevicePropertyBufferFrameSize: New %s buffer size = %d for scope %d", stm,
|
||||
au_type, new_buffer_size, inScope);
|
||||
}
|
||||
stm->buffer_size_change_state = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum set_buffer_size_side {
|
||||
INPUT,
|
||||
OUTPUT,
|
||||
};
|
||||
|
||||
static int
|
||||
audiounit_set_buffer_size(cubeb_stream * stm, uint32_t new_size_frames, set_buffer_size_side set_side)
|
||||
{
|
||||
AudioUnit au = stm->output_unit;
|
||||
AudioUnitScope au_scope = kAudioUnitScope_Input;
|
||||
AudioUnitElement au_element = AU_OUT_BUS;
|
||||
const char * au_type = "output";
|
||||
|
||||
if (set_side == INPUT) {
|
||||
au = stm->input_unit;
|
||||
au_scope = kAudioUnitScope_Output;
|
||||
au_element = AU_IN_BUS;
|
||||
au_type = "input";
|
||||
}
|
||||
|
||||
uint32_t buffer_frames = 0;
|
||||
UInt32 size = sizeof(buffer_frames);
|
||||
int r = AudioUnitGetProperty(au,
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
au_scope,
|
||||
au_element,
|
||||
&buffer_frames,
|
||||
&size);
|
||||
if (r != noErr) {
|
||||
if (set_side == INPUT) {
|
||||
PRINT_ERROR_CODE("AudioUnitGetProperty/input/kAudioDevicePropertyBufferFrameSize", r);
|
||||
} else {
|
||||
PRINT_ERROR_CODE("AudioUnitGetProperty/output/kAudioDevicePropertyBufferFrameSize", r);
|
||||
}
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
if (new_size_frames == buffer_frames) {
|
||||
LOG("(%p) No need to update %s buffer size already %u frames", stm, au_type, buffer_frames);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
r = AudioUnitAddPropertyListener(au,
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
buffer_size_changed_callback,
|
||||
stm);
|
||||
if (r != noErr) {
|
||||
if (set_side == INPUT) {
|
||||
PRINT_ERROR_CODE("AudioUnitAddPropertyListener/input/kAudioDevicePropertyBufferFrameSize", r);
|
||||
} else {
|
||||
PRINT_ERROR_CODE("AudioUnitAddPropertyListener/output/kAudioDevicePropertyBufferFrameSize", r);
|
||||
}
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
stm->buffer_size_change_state = false;
|
||||
|
||||
r = AudioUnitSetProperty(au,
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
au_scope,
|
||||
au_element,
|
||||
&new_size_frames,
|
||||
sizeof(new_size_frames));
|
||||
if (r != noErr) {
|
||||
if (set_side == INPUT) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/input/kAudioDevicePropertyBufferFrameSize", r);
|
||||
} else {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/output/kAudioDevicePropertyBufferFrameSize", r);
|
||||
}
|
||||
|
||||
r = AudioUnitRemovePropertyListenerWithUserData(au,
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
buffer_size_changed_callback,
|
||||
stm);
|
||||
if (r != noErr) {
|
||||
if (set_side == INPUT) {
|
||||
PRINT_ERROR_CODE("AudioUnitAddPropertyListener/input/kAudioDevicePropertyBufferFrameSize", r);
|
||||
} else {
|
||||
PRINT_ERROR_CODE("AudioUnitAddPropertyListener/output/kAudioDevicePropertyBufferFrameSize", r);
|
||||
}
|
||||
}
|
||||
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
while (!stm->buffer_size_change_state && count++ < 30) {
|
||||
struct timespec req, rem;
|
||||
req.tv_sec = 0;
|
||||
req.tv_nsec = 100000000L; // 0.1 sec
|
||||
if (nanosleep(&req , &rem) < 0 ) {
|
||||
LOG("(%p) Warning: nanosleep call failed or interrupted. Remaining time %ld nano secs \n", stm, rem.tv_nsec);
|
||||
}
|
||||
LOG("(%p) audiounit_set_buffer_size : wait count = %d", stm, count);
|
||||
}
|
||||
|
||||
r = AudioUnitRemovePropertyListenerWithUserData(au,
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
buffer_size_changed_callback,
|
||||
stm);
|
||||
if (r != noErr) {
|
||||
if (set_side == INPUT) {
|
||||
PRINT_ERROR_CODE("AudioUnitAddPropertyListener/input/kAudioDevicePropertyBufferFrameSize", r);
|
||||
} else {
|
||||
PRINT_ERROR_CODE("AudioUnitAddPropertyListener/output/kAudioDevicePropertyBufferFrameSize", r);
|
||||
}
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
if (!stm->buffer_size_change_state && count >= 30) {
|
||||
LOG("(%p) Error, did not get buffer size change callback ...", stm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
LOG("(%p) %s buffer size changed to %u frames.", stm, au_type, new_size_frames);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
audiounit_configure_input(cubeb_stream * stm)
|
||||
{
|
||||
int r = 0;
|
||||
UInt32 size;
|
||||
AURenderCallbackStruct aurcbs_in;
|
||||
|
||||
LOG("(%p) Opening input side: rate %u, channels %u, format %d, latency in frames %u.",
|
||||
stm, stm->input_stream_params.rate, stm->input_stream_params.channels,
|
||||
stm->input_stream_params.format, stm->latency_frames);
|
||||
|
||||
/* Get input device sample rate. */
|
||||
AudioStreamBasicDescription input_hw_desc;
|
||||
size = sizeof(AudioStreamBasicDescription);
|
||||
r = AudioUnitGetProperty(stm->input_unit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
AU_IN_BUS,
|
||||
&input_hw_desc,
|
||||
&size);
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitGetProperty/input/kAudioUnitProperty_StreamFormat", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
stm->input_hw_rate = input_hw_desc.mSampleRate;
|
||||
LOG("(%p) Input device sampling rate: %.2f", stm, stm->input_hw_rate);
|
||||
|
||||
/* Set format description according to the input params. */
|
||||
r = audio_stream_desc_init(&stm->input_desc, &stm->input_stream_params);
|
||||
if (r != CUBEB_OK) {
|
||||
LOG("(%p) Setting format description for input failed.", stm);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Use latency to set buffer size
|
||||
stm->input_buffer_frames = stm->latency_frames;
|
||||
r = audiounit_set_buffer_size(stm, stm->input_buffer_frames, INPUT);
|
||||
if (r != CUBEB_OK) {
|
||||
LOG("(%p) Error in change input buffer size.", stm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
AudioStreamBasicDescription src_desc = stm->input_desc;
|
||||
/* Input AudioUnit must be configured with device's sample rate.
|
||||
we will resample inside input callback. */
|
||||
src_desc.mSampleRate = stm->input_hw_rate;
|
||||
|
||||
r = AudioUnitSetProperty(stm->input_unit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Output,
|
||||
AU_IN_BUS,
|
||||
&src_desc,
|
||||
sizeof(AudioStreamBasicDescription));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/input/kAudioUnitProperty_StreamFormat", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
/* Frames per buffer in the input callback. */
|
||||
r = AudioUnitSetProperty(stm->input_unit,
|
||||
kAudioUnitProperty_MaximumFramesPerSlice,
|
||||
kAudioUnitScope_Global,
|
||||
AU_IN_BUS,
|
||||
&stm->input_buffer_frames,
|
||||
sizeof(UInt32));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/input/kAudioUnitProperty_MaximumFramesPerSlice", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
// Input only capacity
|
||||
unsigned int array_capacity = 1;
|
||||
if (has_output(stm)) {
|
||||
// Full-duplex increase capacity
|
||||
array_capacity = 8;
|
||||
}
|
||||
if (audiounit_init_input_linear_buffer(stm, array_capacity) != CUBEB_OK) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
assert(stm->input_unit != NULL);
|
||||
aurcbs_in.inputProc = audiounit_input_callback;
|
||||
aurcbs_in.inputProcRefCon = stm;
|
||||
|
||||
r = AudioUnitSetProperty(stm->input_unit,
|
||||
kAudioOutputUnitProperty_SetInputCallback,
|
||||
kAudioUnitScope_Global,
|
||||
AU_OUT_BUS,
|
||||
&aurcbs_in,
|
||||
sizeof(aurcbs_in));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/input/kAudioOutputUnitProperty_SetInputCallback", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
LOG("(%p) Input audiounit init successfully.", stm);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
audiounit_configure_output(cubeb_stream * stm)
|
||||
{
|
||||
int r;
|
||||
AURenderCallbackStruct aurcbs_out;
|
||||
UInt32 size;
|
||||
|
||||
|
||||
LOG("(%p) Opening output side: rate %u, channels %u, format %d, latency in frames %u.",
|
||||
stm, stm->output_stream_params.rate, stm->output_stream_params.channels,
|
||||
stm->output_stream_params.format, stm->latency_frames);
|
||||
|
||||
r = audio_stream_desc_init(&stm->output_desc, &stm->output_stream_params);
|
||||
if (r != CUBEB_OK) {
|
||||
LOG("(%p) Could not initialize the audio stream description.", stm);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Get output device sample rate. */
|
||||
AudioStreamBasicDescription output_hw_desc;
|
||||
size = sizeof(AudioStreamBasicDescription);
|
||||
memset(&output_hw_desc, 0, size);
|
||||
r = AudioUnitGetProperty(stm->output_unit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Output,
|
||||
AU_OUT_BUS,
|
||||
&output_hw_desc,
|
||||
&size);
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitGetProperty/output/tkAudioUnitProperty_StreamFormat", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
stm->output_hw_rate = output_hw_desc.mSampleRate;
|
||||
LOG("(%p) Output device sampling rate: %.2f", stm, output_hw_desc.mSampleRate);
|
||||
|
||||
r = AudioUnitSetProperty(stm->output_unit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
AU_OUT_BUS,
|
||||
&stm->output_desc,
|
||||
sizeof(AudioStreamBasicDescription));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/output/kAudioUnitProperty_StreamFormat", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
r = audiounit_set_buffer_size(stm, stm->latency_frames, OUTPUT);
|
||||
if (r != CUBEB_OK) {
|
||||
LOG("(%p) Error in change output buffer size.", stm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
/* Frames per buffer in the input callback. */
|
||||
r = AudioUnitSetProperty(stm->output_unit,
|
||||
kAudioUnitProperty_MaximumFramesPerSlice,
|
||||
kAudioUnitScope_Global,
|
||||
AU_OUT_BUS,
|
||||
&stm->latency_frames,
|
||||
sizeof(UInt32));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/output/kAudioUnitProperty_MaximumFramesPerSlice", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
assert(stm->output_unit != NULL);
|
||||
aurcbs_out.inputProc = audiounit_output_callback;
|
||||
aurcbs_out.inputProcRefCon = stm;
|
||||
r = AudioUnitSetProperty(stm->output_unit,
|
||||
kAudioUnitProperty_SetRenderCallback,
|
||||
kAudioUnitScope_Global,
|
||||
AU_OUT_BUS,
|
||||
&aurcbs_out,
|
||||
sizeof(aurcbs_out));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/output/kAudioUnitProperty_SetRenderCallback", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
LOG("(%p) Output audiounit init successfully.", stm);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
audiounit_setup_stream(cubeb_stream * stm)
|
||||
{
|
||||
stm->mutex.assert_current_thread_owns();
|
||||
|
||||
int r = 0;
|
||||
if (has_input(stm)) {
|
||||
r = audiounit_create_unit(&stm->input_unit, true,
|
||||
&stm->input_stream_params,
|
||||
|
@ -1193,170 +1568,36 @@ setup_audiounit_stream(cubeb_stream * stm)
|
|||
}
|
||||
}
|
||||
|
||||
/* Latency cannot change if another stream is operating in parallel. In this case
|
||||
* latecy is set to the other stream value. */
|
||||
if (stm->context->active_streams > 1) {
|
||||
LOG("(%p) More than one active stream, use global latency.", stm);
|
||||
stm->latency_frames = stm->context->global_latency_frames;
|
||||
} else {
|
||||
/* Silently clamp the latency down to the platform default, because we
|
||||
* synthetize the clock from the callbacks, and we want the clock to update
|
||||
* often. */
|
||||
stm->latency_frames = audiounit_clamp_latency(stm, stm->latency_frames);
|
||||
assert(stm->latency_frames); // Ungly error check
|
||||
audiounit_set_global_latency(stm, stm->latency_frames);
|
||||
}
|
||||
|
||||
/* Setup Input Stream! */
|
||||
if (has_input(stm)) {
|
||||
LOG("(%p) Opening input side: rate %u, channels %u, format %d, latency in frames %u.",
|
||||
stm, stm->input_stream_params.rate, stm->input_stream_params.channels,
|
||||
stm->input_stream_params.format, stm->latency_frames);
|
||||
/* Get input device sample rate. */
|
||||
AudioStreamBasicDescription input_hw_desc;
|
||||
size = sizeof(AudioStreamBasicDescription);
|
||||
r = AudioUnitGetProperty(stm->input_unit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
AU_IN_BUS,
|
||||
&input_hw_desc,
|
||||
&size);
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitGetProperty/input/kAudioUnitProperty_StreamFormat", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
stm->input_hw_rate = input_hw_desc.mSampleRate;
|
||||
LOG("(%p) Input device sampling rate: %.2f", stm, stm->input_hw_rate);
|
||||
|
||||
/* Set format description according to the input params. */
|
||||
r = audio_stream_desc_init(&stm->input_desc, &stm->input_stream_params);
|
||||
r = audiounit_configure_input(stm);
|
||||
if (r != CUBEB_OK) {
|
||||
LOG("(%p) Setting format description for input failed.", stm);
|
||||
LOG("(%p) Configure audiounit input failed.", stm);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Use latency to set buffer size
|
||||
stm->input_buffer_frames = stm->latency_frames;
|
||||
LOG("(%p) Input buffer frame count %u.", stm, unsigned(stm->input_buffer_frames));
|
||||
r = AudioUnitSetProperty(stm->input_unit,
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
kAudioUnitScope_Output,
|
||||
AU_IN_BUS,
|
||||
&stm->input_buffer_frames,
|
||||
sizeof(UInt32));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/input/kAudioDevicePropertyBufferFrameSize", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
AudioStreamBasicDescription src_desc = stm->input_desc;
|
||||
/* Input AudioUnit must be configured with device's sample rate.
|
||||
we will resample inside input callback. */
|
||||
src_desc.mSampleRate = stm->input_hw_rate;
|
||||
|
||||
r = AudioUnitSetProperty(stm->input_unit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Output,
|
||||
AU_IN_BUS,
|
||||
&src_desc,
|
||||
sizeof(AudioStreamBasicDescription));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/input/kAudioUnitProperty_StreamFormat", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
/* Frames per buffer in the input callback. */
|
||||
r = AudioUnitSetProperty(stm->input_unit,
|
||||
kAudioUnitProperty_MaximumFramesPerSlice,
|
||||
kAudioUnitScope_Output,
|
||||
AU_IN_BUS,
|
||||
&stm->input_buffer_frames,
|
||||
sizeof(UInt32));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/input/kAudioUnitProperty_MaximumFramesPerSlice", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
// Input only capacity
|
||||
unsigned int array_capacity = 1;
|
||||
if (has_output(stm)) {
|
||||
// Full-duplex increase capacity
|
||||
array_capacity = 8;
|
||||
}
|
||||
if (audiounit_init_input_linear_buffer(stm, array_capacity) != CUBEB_OK) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
assert(stm->input_unit != NULL);
|
||||
aurcbs_in.inputProc = audiounit_input_callback;
|
||||
aurcbs_in.inputProcRefCon = stm;
|
||||
|
||||
r = AudioUnitSetProperty(stm->input_unit,
|
||||
kAudioOutputUnitProperty_SetInputCallback,
|
||||
kAudioUnitScope_Global,
|
||||
AU_OUT_BUS,
|
||||
&aurcbs_in,
|
||||
sizeof(aurcbs_in));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/input/kAudioOutputUnitProperty_SetInputCallback", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
LOG("(%p) Input audiounit init successfully.", stm);
|
||||
}
|
||||
|
||||
/* Setup Output Stream! */
|
||||
if (has_output(stm)) {
|
||||
LOG("(%p) Opening output side: rate %u, channels %u, format %d, latency in frames %u.",
|
||||
stm, stm->output_stream_params.rate, stm->output_stream_params.channels,
|
||||
stm->output_stream_params.format, stm->latency_frames);
|
||||
r = audio_stream_desc_init(&stm->output_desc, &stm->output_stream_params);
|
||||
r = audiounit_configure_output(stm);
|
||||
if (r != CUBEB_OK) {
|
||||
LOG("(%p) Could not initialize the audio stream description.", stm);
|
||||
LOG("(%p) Configure audiounit output failed.", stm);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Get output device sample rate. */
|
||||
AudioStreamBasicDescription output_hw_desc;
|
||||
size = sizeof(AudioStreamBasicDescription);
|
||||
memset(&output_hw_desc, 0, size);
|
||||
r = AudioUnitGetProperty(stm->output_unit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Output,
|
||||
AU_OUT_BUS,
|
||||
&output_hw_desc,
|
||||
&size);
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitGetProperty/output/tkAudioUnitProperty_StreamFormat", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
stm->output_hw_rate = output_hw_desc.mSampleRate;
|
||||
LOG("(%p) Output device sampling rate: %.2f", stm, output_hw_desc.mSampleRate);
|
||||
|
||||
r = AudioUnitSetProperty(stm->output_unit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
AU_OUT_BUS,
|
||||
&stm->output_desc,
|
||||
sizeof(AudioStreamBasicDescription));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/output/kAudioUnitProperty_StreamFormat", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
// Use latency to calculate buffer size
|
||||
uint32_t output_buffer_frames = stm->latency_frames;
|
||||
LOG("(%p) Output buffer frame count %u.", stm, output_buffer_frames);
|
||||
r = AudioUnitSetProperty(stm->output_unit,
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
kAudioUnitScope_Input,
|
||||
AU_OUT_BUS,
|
||||
&output_buffer_frames,
|
||||
sizeof(output_buffer_frames));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/output/kAudioDevicePropertyBufferFrameSize", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
assert(stm->output_unit != NULL);
|
||||
aurcbs_out.inputProc = audiounit_output_callback;
|
||||
aurcbs_out.inputProcRefCon = stm;
|
||||
r = AudioUnitSetProperty(stm->output_unit,
|
||||
kAudioUnitProperty_SetRenderCallback,
|
||||
kAudioUnitScope_Global,
|
||||
AU_OUT_BUS,
|
||||
&aurcbs_out,
|
||||
sizeof(aurcbs_out));
|
||||
if (r != noErr) {
|
||||
PRINT_ERROR_CODE("AudioUnitSetProperty/output/kAudioUnitProperty_SetRenderCallback", r);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
LOG("(%p) Output audiounit init successfully.", stm);
|
||||
}
|
||||
|
||||
// Setting the latency doesn't work well for USB headsets (eg. plantronics).
|
||||
|
@ -1486,14 +1727,12 @@ audiounit_stream_init(cubeb * context,
|
|||
|
||||
assert(context);
|
||||
*stream = NULL;
|
||||
|
||||
assert(latency_frames > 0);
|
||||
if ((input_device && !input_stream_params) ||
|
||||
(output_device && !output_stream_params)) {
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
context->active_streams += 1;
|
||||
|
||||
stm.reset(new cubeb_stream(context));
|
||||
|
||||
/* These could be different in the future if we have both
|
||||
|
@ -1501,6 +1740,7 @@ audiounit_stream_init(cubeb * context,
|
|||
stm->data_callback = data_callback;
|
||||
stm->state_callback = state_callback;
|
||||
stm->user_ptr = user_ptr;
|
||||
stm->latency_frames = latency_frames;
|
||||
if (input_stream_params) {
|
||||
stm->input_stream_params = *input_stream_params;
|
||||
stm->input_device = reinterpret_cast<uintptr_t>(input_device);
|
||||
|
@ -1512,18 +1752,14 @@ audiounit_stream_init(cubeb * context,
|
|||
stm->output_device = reinterpret_cast<uintptr_t>(output_device);
|
||||
}
|
||||
|
||||
/* Silently clamp the latency down to the platform default, because we
|
||||
* synthetize the clock from the callbacks, and we want the clock to update
|
||||
* often. */
|
||||
stm->latency_frames = audiounit_clamp_latency(stm.get(), latency_frames);
|
||||
assert(latency_frames > 0);
|
||||
|
||||
auto_lock context_lock(context->mutex);
|
||||
{
|
||||
// It's not critical to lock here, because no other thread has been started
|
||||
// yet, but it allows to assert that the lock has been taken in
|
||||
// `setup_audiounit_stream`.
|
||||
// `audiounit_setup_stream`.
|
||||
context->active_streams += 1;
|
||||
auto_lock lock(stm->mutex);
|
||||
r = setup_audiounit_stream(stm.get());
|
||||
r = audiounit_setup_stream(stm.get());
|
||||
}
|
||||
|
||||
if (r != CUBEB_OK) {
|
||||
|
@ -1543,7 +1779,7 @@ audiounit_stream_init(cubeb * context,
|
|||
}
|
||||
|
||||
static void
|
||||
close_audiounit_stream(cubeb_stream * stm)
|
||||
audiounit_close_stream(cubeb_stream *stm)
|
||||
{
|
||||
stm->mutex.assert_current_thread_owns();
|
||||
if (stm->input_unit) {
|
||||
|
@ -1566,11 +1802,12 @@ audiounit_stream_destroy(cubeb_stream * stm)
|
|||
{
|
||||
stm->shutdown = true;
|
||||
|
||||
auto_lock context_locl(stm->context->mutex);
|
||||
audiounit_stream_stop_internal(stm);
|
||||
|
||||
{
|
||||
auto_lock lock(stm->mutex);
|
||||
close_audiounit_stream(stm);
|
||||
audiounit_close_stream(stm);
|
||||
}
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
|
@ -1583,6 +1820,7 @@ audiounit_stream_destroy(cubeb_stream * stm)
|
|||
assert(stm->context->active_streams >= 1);
|
||||
stm->context->active_streams -= 1;
|
||||
|
||||
LOG("Cubeb stream (%p) destroyed successful.", stm);
|
||||
delete stm;
|
||||
}
|
||||
|
||||
|
@ -1606,6 +1844,7 @@ audiounit_stream_start(cubeb_stream * stm)
|
|||
stm->shutdown = false;
|
||||
stm->draining = false;
|
||||
|
||||
auto_lock context_locl(stm->context->mutex);
|
||||
audiounit_stream_start_internal(stm);
|
||||
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STARTED);
|
||||
|
@ -1633,6 +1872,7 @@ audiounit_stream_stop(cubeb_stream * stm)
|
|||
{
|
||||
stm->shutdown = true;
|
||||
|
||||
auto_lock context_locl(stm->context->mutex);
|
||||
audiounit_stream_stop_internal(stm);
|
||||
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
|
||||
|
@ -2294,6 +2534,7 @@ cubeb_ops const audiounit_ops = {
|
|||
/*.get_max_channel_count =*/ audiounit_get_max_channel_count,
|
||||
/*.get_min_latency =*/ audiounit_get_min_latency,
|
||||
/*.get_preferred_sample_rate =*/ audiounit_get_preferred_sample_rate,
|
||||
/*.get_preferred_channel_layout =*/ nullptr,
|
||||
/*.enumerate_devices =*/ audiounit_enumerate_devices,
|
||||
/*.destroy =*/ audiounit_destroy,
|
||||
/*.stream_init =*/ audiounit_stream_init,
|
||||
|
|
|
@ -114,6 +114,7 @@ static struct cubeb_ops const cbjack_ops = {
|
|||
.get_max_channel_count = cbjack_get_max_channel_count,
|
||||
.get_min_latency = cbjack_get_min_latency,
|
||||
.get_preferred_sample_rate = cbjack_get_preferred_sample_rate,
|
||||
.get_preferred_channel_layout = NULL,
|
||||
.enumerate_devices = cbjack_enumerate_devices,
|
||||
.destroy = cbjack_destroy,
|
||||
.stream_init = cbjack_stream_init,
|
||||
|
@ -420,7 +421,6 @@ cbjack_process(jack_nframes_t nframes, void * arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cbjack_deinterleave_playback_refill_float(cubeb_stream * stream, float ** in, float ** bufs_out, jack_nframes_t nframes)
|
||||
{
|
||||
|
@ -433,7 +433,6 @@ cbjack_deinterleave_playback_refill_float(cubeb_stream * stream, float ** in, fl
|
|||
long done_frames = 0;
|
||||
long input_frames_count = (in != NULL) ? nframes : 0;
|
||||
|
||||
|
||||
done_frames = cubeb_resampler_fill(stream->resampler,
|
||||
inptr,
|
||||
&input_frames_count,
|
||||
|
@ -934,7 +933,6 @@ cbjack_stream_set_volume(cubeb_stream * stm, float volume)
|
|||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cbjack_stream_get_current_device(cubeb_stream * stm, cubeb_device ** const device)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
* Copyright © 2016 Mozilla Foundation
|
||||
*
|
||||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include "cubeb-internal.h"
|
||||
#include "cubeb_mixer.h"
|
||||
|
||||
cubeb_layout_map const CUBEB_CHANNEL_LAYOUT_MAPS[CUBEB_LAYOUT_MAX] = {
|
||||
{ "undefined", 0, CUBEB_LAYOUT_UNDEFINED },
|
||||
{ "dual mono", 2, CUBEB_LAYOUT_DUAL_MONO },
|
||||
{ "dual mono lfe", 3, CUBEB_LAYOUT_DUAL_MONO_LFE },
|
||||
{ "mono", 1, CUBEB_LAYOUT_MONO },
|
||||
{ "mono lfe", 2, CUBEB_LAYOUT_MONO_LFE },
|
||||
{ "stereo", 2, CUBEB_LAYOUT_STEREO },
|
||||
{ "stereo lfe", 3, CUBEB_LAYOUT_STEREO_LFE },
|
||||
{ "3f", 3, CUBEB_LAYOUT_3F },
|
||||
{ "3f lfe", 4, CUBEB_LAYOUT_3F_LFE },
|
||||
{ "2f1", 3, CUBEB_LAYOUT_2F1 },
|
||||
{ "2f1 lfe", 4, CUBEB_LAYOUT_2F1_LFE },
|
||||
{ "3f1", 4, CUBEB_LAYOUT_3F1 },
|
||||
{ "3f1 lfe", 5, CUBEB_LAYOUT_3F1_LFE },
|
||||
{ "2f2", 4, CUBEB_LAYOUT_2F2 },
|
||||
{ "2f2 lfe", 5, CUBEB_LAYOUT_2F2_LFE },
|
||||
{ "3f2", 5, CUBEB_LAYOUT_3F2 },
|
||||
{ "3f2 lfe", 6, CUBEB_LAYOUT_3F2_LFE },
|
||||
{ "3f3r lfe", 7, CUBEB_LAYOUT_3F3R_LFE },
|
||||
{ "3f4 lfe", 8, CUBEB_LAYOUT_3F4_LFE }
|
||||
};
|
||||
|
||||
static int const CHANNEL_ORDER_TO_INDEX[CUBEB_LAYOUT_MAX][CHANNEL_MAX] = {
|
||||
// M | L | R | C | LS | RS | RLS | RC | RRS | LFE
|
||||
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // UNDEFINED
|
||||
{ -1, 0, 1, -1, -1, -1, -1, -1, -1, -1 }, // DUAL_MONO
|
||||
{ -1, 0, 1, -1, -1, -1, -1, -1, -1, 2 }, // DUAL_MONO_LFE
|
||||
{ 0, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // MONO
|
||||
{ 0, -1, -1, -1, -1, -1, -1, -1, -1, 1 }, // MONO_LFE
|
||||
{ -1, 0, 1, -1, -1, -1, -1, -1, -1, -1 }, // STEREO
|
||||
{ -1, 0, 1, -1, -1, -1, -1, -1, -1, 2 }, // STEREO_LFE
|
||||
{ -1, 0, 1, 2, -1, -1, -1, -1, -1, -1 }, // 3F
|
||||
{ -1, 0, 1, 2, -1, -1, -1, -1, -1, 3 }, // 3F_LFE
|
||||
{ -1, 0, 1, -1, -1, -1, -1, 2, -1, -1 }, // 2F1
|
||||
{ -1, 0, 1, -1, -1, -1, -1, 3, -1, 2 }, // 2F1_LFE
|
||||
{ -1, 0, 1, 2, -1, -1, -1, 3, -1, -1 }, // 3F1
|
||||
{ -1, 0, 1, 2, -1, -1, -1, 4, -1, 3 }, // 3F1_LFE
|
||||
{ -1, 0, 1, -1, 2, 3, -1, -1, -1, -1 }, // 2F2
|
||||
{ -1, 0, 1, -1, 3, 4, -1, -1, -1, 2 }, // 2F2_LFE
|
||||
{ -1, 0, 1, 2, 3, 4, -1, -1, -1, -1 }, // 3F2
|
||||
{ -1, 0, 1, 2, 4, 5, -1, -1, -1, 3 }, // 3F2_LFE
|
||||
{ -1, 0, 1, 2, 5, 6, -1, 4, -1, 3 }, // 3F3R_LFE
|
||||
{ -1, 0, 1, 2, 6, 7, 4, -1, 5, 3 }, // 3F4_LFE
|
||||
};
|
||||
|
||||
// The downmix matrix from TABLE 2 in the ITU-R BS.775-3[1] defines a way to
|
||||
// convert 3F2 input data to 1F, 2F, 3F, 2F1, 3F1, 2F2 output data. We extend it
|
||||
// to convert 3F2-LFE input data to 1F, 2F, 3F, 2F1, 3F1, 2F2 and their LFEs
|
||||
// output data.
|
||||
// [1] https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.775-3-201208-I!!PDF-E.pdf
|
||||
|
||||
// Number of converted layouts: 1F, 2F, 3F, 2F1, 3F1, 2F2 and their LFEs.
|
||||
unsigned int const SUPPORTED_LAYOUT_NUM = 12;
|
||||
// Number of input channel for downmix conversion.
|
||||
unsigned int const INPUT_CHANNEL_NUM = 6; // 3F2-LFE
|
||||
// Max number of possible output channels.
|
||||
unsigned int const MAX_OUTPUT_CHANNEL_NUM = 5; // 2F2-LFE or 3F1-LFE
|
||||
float const INV_SQRT_2 = 0.707106f; // 1/sqrt(2)
|
||||
// Each array contains coefficients that will be multiplied with
|
||||
// { L, R, C, LFE, LS, RS } channels respectively.
|
||||
static float const DOWNMIX_MATRIX_3F2_LFE[SUPPORTED_LAYOUT_NUM][MAX_OUTPUT_CHANNEL_NUM][INPUT_CHANNEL_NUM] =
|
||||
{
|
||||
// 1F Mono
|
||||
{
|
||||
{ INV_SQRT_2, INV_SQRT_2, 1, 0, 0.5, 0.5 }, // M
|
||||
},
|
||||
// 1F Mono-LFE
|
||||
{
|
||||
{ INV_SQRT_2, INV_SQRT_2, 1, 0, 0.5, 0.5 }, // M
|
||||
{ 0, 0, 0, 1, 0, 0 } // LFE
|
||||
},
|
||||
// 2F Stereo
|
||||
{
|
||||
{ 1, 0, INV_SQRT_2, 0, INV_SQRT_2, 0 }, // L
|
||||
{ 0, 1, INV_SQRT_2, 0, 0, INV_SQRT_2 } // R
|
||||
},
|
||||
// 2F Stereo-LFE
|
||||
{
|
||||
{ 1, 0, INV_SQRT_2, 0, INV_SQRT_2, 0 }, // L
|
||||
{ 0, 1, INV_SQRT_2, 0, 0, INV_SQRT_2 }, // R
|
||||
{ 0, 0, 0, 1, 0, 0 } // LFE
|
||||
},
|
||||
// 3F
|
||||
{
|
||||
{ 1, 0, 0, 0, INV_SQRT_2, 0 }, // L
|
||||
{ 0, 1, 0, 0, 0, INV_SQRT_2 }, // R
|
||||
{ 0, 0, 1, 0, 0, 0 } // C
|
||||
},
|
||||
// 3F-LFE
|
||||
{
|
||||
{ 1, 0, 0, 0, INV_SQRT_2, 0 }, // L
|
||||
{ 0, 1, 0, 0, 0, INV_SQRT_2 }, // R
|
||||
{ 0, 0, 1, 0, 0, 0 }, // C
|
||||
{ 0, 0, 0, 1, 0, 0 } // LFE
|
||||
},
|
||||
// 2F1
|
||||
{
|
||||
{ 1, 0, INV_SQRT_2, 0, 0, 0 }, // L
|
||||
{ 0, 1, INV_SQRT_2, 0, 0, 0 }, // R
|
||||
{ 0, 0, 0, 0, INV_SQRT_2, INV_SQRT_2 } // S
|
||||
},
|
||||
// 2F1-LFE
|
||||
{
|
||||
{ 1, 0, INV_SQRT_2, 0, 0, 0 }, // L
|
||||
{ 0, 1, INV_SQRT_2, 0, 0, 0 }, // R
|
||||
{ 0, 0, 0, 1, 0, 0 }, // LFE
|
||||
{ 0, 0, 0, 0, INV_SQRT_2, INV_SQRT_2 } // S
|
||||
},
|
||||
// 3F1
|
||||
{
|
||||
{ 1, 0, 0, 0, 0, 0 }, // L
|
||||
{ 0, 1, 0, 0, 0, 0 }, // R
|
||||
{ 0, 0, 1, 0, 0, 0 }, // C
|
||||
{ 0, 0, 0, 0, INV_SQRT_2, INV_SQRT_2 } // S
|
||||
},
|
||||
// 3F1-LFE
|
||||
{
|
||||
{ 1, 0, 0, 0, 0, 0 }, // L
|
||||
{ 0, 1, 0, 0, 0, 0 }, // R
|
||||
{ 0, 0, 1, 0, 0, 0 }, // C
|
||||
{ 0, 0, 0, 1, 0, 0 }, // LFE
|
||||
{ 0, 0, 0, 0, INV_SQRT_2, INV_SQRT_2 } // S
|
||||
},
|
||||
// 2F2
|
||||
{
|
||||
{ 1, 0, INV_SQRT_2, 0, 0, 0 }, // L
|
||||
{ 0, 1, INV_SQRT_2, 0, 0, 0 }, // R
|
||||
{ 0, 0, 0, 0, 1, 0 }, // LS
|
||||
{ 0, 0, 0, 0, 0, 1 } // RS
|
||||
},
|
||||
// 2F2-LFE
|
||||
{
|
||||
{ 1, 0, INV_SQRT_2, 0, 0, 0 }, // L
|
||||
{ 0, 1, INV_SQRT_2, 0, 0, 0 }, // R
|
||||
{ 0, 0, 0, 1, 0, 0 }, // LFE
|
||||
{ 0, 0, 0, 0, 1, 0 }, // LS
|
||||
{ 0, 0, 0, 0, 0, 1 } // RS
|
||||
}
|
||||
};
|
||||
|
||||
/* Convert audio data from 3F2(-LFE) to 1F, 2F, 3F, 2F1, 3F1, 2F2 and their LFEs. */
|
||||
template<typename T>
|
||||
bool
|
||||
downmix_3f2(T const * const in, unsigned long inframes, T * out, cubeb_channel_layout in_layout, cubeb_channel_layout out_layout)
|
||||
{
|
||||
if ((in_layout != CUBEB_LAYOUT_3F2 && in_layout != CUBEB_LAYOUT_3F2_LFE) ||
|
||||
out_layout < CUBEB_LAYOUT_MONO || out_layout > CUBEB_LAYOUT_2F2_LFE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int in_channels = CUBEB_CHANNEL_LAYOUT_MAPS[in_layout].channels;
|
||||
unsigned int out_channels = CUBEB_CHANNEL_LAYOUT_MAPS[out_layout].channels;
|
||||
|
||||
// Conversion from 3F2 to 2F2-LFE or 3F1-LFE is allowed, so we use '<=' instead of '<'.
|
||||
assert(out_channels <= in_channels);
|
||||
|
||||
long out_index = 0;
|
||||
auto & downmix_matrix = DOWNMIX_MATRIX_3F2_LFE[out_layout - CUBEB_LAYOUT_MONO]; // The matrix is started from mono.
|
||||
for (unsigned long i = 0; i < inframes * in_channels; i += in_channels) {
|
||||
for (unsigned int j = 0; j < out_channels; ++j) {
|
||||
out[out_index + j] = 0; // Clear its value.
|
||||
for (unsigned int k = 0 ; k < INPUT_CHANNEL_NUM ; ++k) {
|
||||
// 3F2-LFE has 6 channels: L, R, C, LFE, LS, RS, while 3F2 has only 5
|
||||
// channels: L, R, C, LS, RS. Thus, we need to append 0 to LFE(index 3)
|
||||
// to simulate a 3F2-LFE data when input layout is 3F2.
|
||||
T data = (in_layout == CUBEB_LAYOUT_3F2_LFE) ? in[i + k] : (k == 3) ? 0 : in[i + ((k < 3) ? k : k - 1)];
|
||||
out[out_index + j] += downmix_matrix[j][k] * data;
|
||||
}
|
||||
}
|
||||
out_index += out_channels;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Map the audio data by channel name. */
|
||||
template<class T>
|
||||
bool
|
||||
mix_remap(T const * const in, unsigned long inframes, T * out, cubeb_channel_layout in_layout, cubeb_channel_layout out_layout) {
|
||||
assert(in_layout != out_layout);
|
||||
unsigned int in_channels = CUBEB_CHANNEL_LAYOUT_MAPS[in_layout].channels;
|
||||
unsigned int out_channels = CUBEB_CHANNEL_LAYOUT_MAPS[out_layout].channels;
|
||||
|
||||
uint32_t in_layout_mask = 0;
|
||||
for (unsigned int i = 0 ; i < in_channels ; ++i) {
|
||||
in_layout_mask |= 1 << CHANNEL_INDEX_TO_ORDER[in_layout][i];
|
||||
}
|
||||
|
||||
uint32_t out_layout_mask = 0;
|
||||
for (unsigned int i = 0 ; i < out_channels ; ++i) {
|
||||
out_layout_mask |= 1 << CHANNEL_INDEX_TO_ORDER[out_layout][i];
|
||||
}
|
||||
|
||||
// If there is no matched channel, then do nothing.
|
||||
if (!(out_layout_mask & in_layout_mask)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long out_index = 0;
|
||||
for (unsigned long i = 0; i < inframes * in_channels; i += in_channels) {
|
||||
for (unsigned int j = 0; j < out_channels; ++j) {
|
||||
cubeb_channel channel = CHANNEL_INDEX_TO_ORDER[out_layout][j];
|
||||
uint32_t channel_mask = 1 << channel;
|
||||
int channel_index = CHANNEL_ORDER_TO_INDEX[in_layout][channel];
|
||||
if (in_layout_mask & channel_mask) {
|
||||
assert(channel_index != -1);
|
||||
out[out_index + j] = in[i + channel_index];
|
||||
} else {
|
||||
assert(channel_index == -1);
|
||||
out[out_index + j] = 0;
|
||||
}
|
||||
}
|
||||
out_index += out_channels;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Drop the extra channels beyond the provided output channels. */
|
||||
template<typename T>
|
||||
void
|
||||
downmix_fallback(T const * const in, unsigned long inframes, T * out, unsigned int in_channels, unsigned int out_channels)
|
||||
{
|
||||
assert(in_channels >= out_channels);
|
||||
long out_index = 0;
|
||||
for (unsigned long i = 0; i < inframes * in_channels; i += in_channels) {
|
||||
for (unsigned int j = 0; j < out_channels; ++j) {
|
||||
out[out_index + j] = in[i + j];
|
||||
}
|
||||
out_index += out_channels;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
cubeb_downmix(T const * const in, long inframes, T * out,
|
||||
unsigned int in_channels, unsigned int out_channels,
|
||||
cubeb_channel_layout in_layout, cubeb_channel_layout out_layout)
|
||||
{
|
||||
assert(in_channels >= out_channels && in_layout != CUBEB_LAYOUT_UNDEFINED);
|
||||
|
||||
// If the channel number is different from the layout's setting or it's not a
|
||||
// valid audio 5.1 downmix, then we use fallback downmix mechanism.
|
||||
if (out_channels == CUBEB_CHANNEL_LAYOUT_MAPS[out_layout].channels &&
|
||||
in_channels == CUBEB_CHANNEL_LAYOUT_MAPS[in_layout].channels) {
|
||||
if (downmix_3f2(in, inframes, out, in_layout, out_layout)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mix_remap(in, inframes, out, in_layout, out_layout)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
downmix_fallback(in, inframes, out, in_channels, out_channels);
|
||||
}
|
||||
|
||||
/* Upmix function, copies a mono channel into L and R. */
|
||||
template<typename T>
|
||||
void
|
||||
mono_to_stereo(T const * in, long insamples, T * out, unsigned int out_channels)
|
||||
{
|
||||
for (long i = 0, j = 0; i < insamples; ++i, j += out_channels) {
|
||||
out[j] = out[j + 1] = in[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
cubeb_upmix(T const * in, long inframes, T * out,
|
||||
unsigned int in_channels, unsigned int out_channels)
|
||||
{
|
||||
assert(out_channels >= in_channels && in_channels > 0);
|
||||
|
||||
/* Either way, if we have 2 or more channels, the first two are L and R. */
|
||||
/* If we are playing a mono stream over stereo speakers, copy the data over. */
|
||||
if (in_channels == 1 && out_channels >= 2) {
|
||||
mono_to_stereo(in, inframes, out, out_channels);
|
||||
} else {
|
||||
/* Copy through. */
|
||||
for (unsigned int i = 0, o = 0; i < inframes * in_channels;
|
||||
i += in_channels, o += out_channels) {
|
||||
for (unsigned int j = 0; j < in_channels; ++j) {
|
||||
out[o + j] = in[i + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if more channels. */
|
||||
if (out_channels <= 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Put silence in remaining channels. */
|
||||
for (long i = 0, o = 0; i < inframes; ++i, o += out_channels) {
|
||||
for (unsigned int j = 2; j < out_channels; ++j) {
|
||||
out[o + j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
cubeb_should_upmix(cubeb_stream_params const * stream, cubeb_stream_params const * mixer)
|
||||
{
|
||||
return mixer->channels > stream->channels;
|
||||
}
|
||||
|
||||
bool
|
||||
cubeb_should_downmix(cubeb_stream_params const * stream, cubeb_stream_params const * mixer)
|
||||
{
|
||||
if (mixer->channels > stream->channels || mixer->layout == stream->layout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mixer->channels < stream->channels ||
|
||||
// When mixer.channels == stream.channels
|
||||
mixer->layout == CUBEB_LAYOUT_UNDEFINED || // fallback downmix
|
||||
(stream->layout == CUBEB_LAYOUT_3F2 && // 3f2 downmix
|
||||
(mixer->layout == CUBEB_LAYOUT_2F2_LFE ||
|
||||
mixer->layout == CUBEB_LAYOUT_3F1_LFE));
|
||||
}
|
||||
|
||||
void
|
||||
cubeb_downmix_float(float * const in, long inframes, float * out,
|
||||
unsigned int in_channels, unsigned int out_channels,
|
||||
cubeb_channel_layout in_layout, cubeb_channel_layout out_layout)
|
||||
{
|
||||
cubeb_downmix(in, inframes, out, in_channels, out_channels, in_layout, out_layout);
|
||||
}
|
||||
|
||||
void
|
||||
cubeb_upmix_float(float * const in, long inframes, float * out,
|
||||
unsigned int in_channels, unsigned int out_channels)
|
||||
{
|
||||
cubeb_upmix(in, inframes, out, in_channels, out_channels);
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright © 2016 Mozilla Foundation
|
||||
*
|
||||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef CUBEB_MIXER
|
||||
#define CUBEB_MIXER
|
||||
|
||||
#include "cubeb/cubeb.h" // for cubeb_channel_layout ,CUBEB_CHANNEL_LAYOUT_MAPS and cubeb_stream_params.
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CHANNEL_INVALID = -1,
|
||||
CHANNEL_MONO = 0,
|
||||
CHANNEL_LEFT,
|
||||
CHANNEL_RIGHT,
|
||||
CHANNEL_CENTER,
|
||||
CHANNEL_LS,
|
||||
CHANNEL_RS,
|
||||
CHANNEL_RLS,
|
||||
CHANNEL_RCENTER,
|
||||
CHANNEL_RRS,
|
||||
CHANNEL_LFE,
|
||||
CHANNEL_MAX // Max number of supported channels.
|
||||
} cubeb_channel;
|
||||
|
||||
static cubeb_channel const CHANNEL_INDEX_TO_ORDER[CUBEB_LAYOUT_MAX][CHANNEL_MAX] = {
|
||||
{ CHANNEL_INVALID }, // UNDEFINED
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT }, // DUAL_MONO
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_LFE }, // DUAL_MONO_LFE
|
||||
{ CHANNEL_MONO }, // MONO
|
||||
{ CHANNEL_MONO, CHANNEL_LFE }, // MONO_LFE
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT }, // STEREO
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_LFE }, // STEREO_LFE
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER }, // 3F
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE }, // 3F_LFE
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_RCENTER }, // 2F1
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_LFE, CHANNEL_RCENTER }, // 2F1_LFE
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_RCENTER }, // 3F1
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_RCENTER }, // 3F1_LFE
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_LS, CHANNEL_RS }, // 2F2
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_LFE, CHANNEL_LS, CHANNEL_RS }, // 2F2_LFE
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LS, CHANNEL_RS }, // 3F2
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_LS, CHANNEL_RS }, // 3F2_LFE
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_RCENTER, CHANNEL_LS, CHANNEL_RS }, // 3F3R_LFE
|
||||
{ CHANNEL_LEFT, CHANNEL_RIGHT, CHANNEL_CENTER, CHANNEL_LFE, CHANNEL_RLS, CHANNEL_RRS, CHANNEL_LS, CHANNEL_RS } // 3F4_LFE
|
||||
};
|
||||
|
||||
bool cubeb_should_upmix(cubeb_stream_params const * stream, cubeb_stream_params const * mixer);
|
||||
|
||||
bool cubeb_should_downmix(cubeb_stream_params const * stream, cubeb_stream_params const * mixer);
|
||||
|
||||
void cubeb_downmix_float(float * const in, long inframes, float * out,
|
||||
unsigned int in_channels, unsigned int out_channels,
|
||||
cubeb_channel_layout in_layout, cubeb_channel_layout out_layout);
|
||||
|
||||
void cubeb_upmix_float(float * const in, long inframes, float * out,
|
||||
unsigned int in_channels, unsigned int out_channels);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CUBEB_MIXER
|
|
@ -1740,6 +1740,7 @@ static struct cubeb_ops const opensl_ops = {
|
|||
.get_max_channel_count = opensl_get_max_channel_count,
|
||||
.get_min_latency = opensl_get_min_latency,
|
||||
.get_preferred_sample_rate = opensl_get_preferred_sample_rate,
|
||||
.get_preferred_channel_layout = NULL,
|
||||
.enumerate_devices = NULL,
|
||||
.destroy = opensl_destroy,
|
||||
.stream_init = opensl_stream_init,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <string.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "cubeb-internal.h"
|
||||
#include "cubeb_mixer.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef DISABLE_LIBPULSE_DLOPEN
|
||||
|
@ -20,7 +21,7 @@
|
|||
#define WRAP(x) cubeb_##x
|
||||
#define LIBPULSE_API_VISIT(X) \
|
||||
X(pa_channel_map_can_balance) \
|
||||
X(pa_channel_map_init_auto) \
|
||||
X(pa_channel_map_init) \
|
||||
X(pa_context_connect) \
|
||||
X(pa_context_disconnect) \
|
||||
X(pa_context_drain) \
|
||||
|
@ -468,6 +469,113 @@ stream_update_timing_info(cubeb_stream * stm)
|
|||
return r;
|
||||
}
|
||||
|
||||
static pa_channel_position_t
|
||||
cubeb_channel_to_pa_channel(cubeb_channel channel)
|
||||
{
|
||||
assert(channel != CHANNEL_INVALID);
|
||||
|
||||
// This variable may be used for multiple times, so we should avoid to
|
||||
// allocate it in stack, or it will be created and removed repeatedly.
|
||||
// Use static to allocate this local variable in data space instead of stack.
|
||||
static pa_channel_position_t map[CHANNEL_MAX] = {
|
||||
// PA_CHANNEL_POSITION_INVALID, // CHANNEL_INVALID
|
||||
PA_CHANNEL_POSITION_MONO, // CHANNEL_MONO
|
||||
PA_CHANNEL_POSITION_FRONT_LEFT, // CHANNEL_LEFT
|
||||
PA_CHANNEL_POSITION_FRONT_RIGHT, // CHANNEL_RIGHT
|
||||
PA_CHANNEL_POSITION_FRONT_CENTER, // CHANNEL_CENTER
|
||||
PA_CHANNEL_POSITION_SIDE_LEFT, // CHANNEL_LS
|
||||
PA_CHANNEL_POSITION_SIDE_RIGHT, // CHANNEL_RS
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, // CHANNEL_RLS
|
||||
PA_CHANNEL_POSITION_REAR_CENTER, // CHANNEL_RCENTER
|
||||
PA_CHANNEL_POSITION_REAR_RIGHT, // CHANNEL_RRS
|
||||
PA_CHANNEL_POSITION_LFE // CHANNEL_LFE
|
||||
};
|
||||
|
||||
return map[channel];
|
||||
}
|
||||
|
||||
static cubeb_channel
|
||||
pa_channel_to_cubeb_channel(pa_channel_position_t channel)
|
||||
{
|
||||
assert(channel != PA_CHANNEL_POSITION_INVALID);
|
||||
switch(channel) {
|
||||
case PA_CHANNEL_POSITION_MONO: return CHANNEL_MONO;
|
||||
case PA_CHANNEL_POSITION_FRONT_LEFT: return CHANNEL_LEFT;
|
||||
case PA_CHANNEL_POSITION_FRONT_RIGHT: return CHANNEL_RIGHT;
|
||||
case PA_CHANNEL_POSITION_FRONT_CENTER: return CHANNEL_CENTER;
|
||||
case PA_CHANNEL_POSITION_SIDE_LEFT: return CHANNEL_LS;
|
||||
case PA_CHANNEL_POSITION_SIDE_RIGHT: return CHANNEL_RS;
|
||||
case PA_CHANNEL_POSITION_REAR_LEFT: return CHANNEL_RLS;
|
||||
case PA_CHANNEL_POSITION_REAR_CENTER: return CHANNEL_RCENTER;
|
||||
case PA_CHANNEL_POSITION_REAR_RIGHT: return CHANNEL_RRS;
|
||||
case PA_CHANNEL_POSITION_LFE: return CHANNEL_LFE;
|
||||
default: return CHANNEL_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
layout_to_channel_map(cubeb_channel_layout layout, pa_channel_map * cm)
|
||||
{
|
||||
assert(cm && layout != CUBEB_LAYOUT_UNDEFINED);
|
||||
|
||||
WRAP(pa_channel_map_init)(cm);
|
||||
cm->channels = CUBEB_CHANNEL_LAYOUT_MAPS[layout].channels;
|
||||
for (uint8_t i = 0 ; i < cm->channels ; ++i) {
|
||||
cm->map[i] = cubeb_channel_to_pa_channel(CHANNEL_INDEX_TO_ORDER[layout][i]);
|
||||
}
|
||||
}
|
||||
|
||||
// DUAL_MONO(_LFE) is same as STEREO(_LFE).
|
||||
#define MASK_MONO (1 << CHANNEL_MONO)
|
||||
#define MASK_MONO_LFE (MASK_MONO | (1 << CHANNEL_LFE))
|
||||
#define MASK_STEREO ((1 << CHANNEL_LEFT) | (1 << CHANNEL_RIGHT))
|
||||
#define MASK_STEREO_LFE (MASK_STEREO | (1 << CHANNEL_LFE))
|
||||
#define MASK_3F (MASK_STEREO | (1 << CHANNEL_CENTER))
|
||||
#define MASK_3F_LFE (MASK_3F | (1 << CHANNEL_LFE))
|
||||
#define MASK_2F1 (MASK_STEREO | (1 << CHANNEL_RCENTER))
|
||||
#define MASK_2F1_LFE (MASK_2F1 | (1 << CHANNEL_LFE))
|
||||
#define MASK_3F1 (MASK_3F | (1 << CHANNEL_RCENTER))
|
||||
#define MASK_3F1_LFE (MASK_3F1 | (1 << CHANNEL_LFE))
|
||||
#define MASK_2F2 (MASK_STEREO | (1 << CHANNEL_LS) | (1 << CHANNEL_RS))
|
||||
#define MASK_2F2_LFE (MASK_2F2 | (1 << CHANNEL_LFE))
|
||||
#define MASK_3F2 (MASK_2F2 | (1 << CHANNEL_CENTER))
|
||||
#define MASK_3F2_LFE (MASK_3F2 | (1 << CHANNEL_LFE))
|
||||
#define MASK_3F3R_LFE (MASK_3F2_LFE | (1 << CHANNEL_RCENTER))
|
||||
#define MASK_3F4_LFE (MASK_3F2_LFE | (1 << CHANNEL_RLS) | (1 << CHANNEL_RRS))
|
||||
|
||||
static cubeb_channel_layout
|
||||
channel_map_to_layout(pa_channel_map * cm)
|
||||
{
|
||||
uint32_t channel_mask = 0;
|
||||
for (uint8_t i = 0 ; i < cm->channels ; ++i) {
|
||||
cubeb_channel channel = pa_channel_to_cubeb_channel(cm->map[i]);
|
||||
if (channel == CHANNEL_INVALID) {
|
||||
return CUBEB_LAYOUT_UNDEFINED;
|
||||
}
|
||||
channel_mask |= 1 << channel;
|
||||
}
|
||||
|
||||
switch(channel_mask) {
|
||||
case MASK_MONO: return CUBEB_LAYOUT_MONO;
|
||||
case MASK_MONO_LFE: return CUBEB_LAYOUT_MONO_LFE;
|
||||
case MASK_STEREO: return CUBEB_LAYOUT_STEREO;
|
||||
case MASK_STEREO_LFE: return CUBEB_LAYOUT_STEREO_LFE;
|
||||
case MASK_3F: return CUBEB_LAYOUT_3F;
|
||||
case MASK_3F_LFE: return CUBEB_LAYOUT_3F_LFE;
|
||||
case MASK_2F1: return CUBEB_LAYOUT_2F1;
|
||||
case MASK_2F1_LFE: return CUBEB_LAYOUT_2F1_LFE;
|
||||
case MASK_3F1: return CUBEB_LAYOUT_3F1;
|
||||
case MASK_3F1_LFE: return CUBEB_LAYOUT_3F1_LFE;
|
||||
case MASK_2F2: return CUBEB_LAYOUT_2F2;
|
||||
case MASK_2F2_LFE: return CUBEB_LAYOUT_2F2_LFE;
|
||||
case MASK_3F2: return CUBEB_LAYOUT_3F2;
|
||||
case MASK_3F2_LFE: return CUBEB_LAYOUT_3F2_LFE;
|
||||
case MASK_3F3R_LFE: return CUBEB_LAYOUT_3F3R_LFE;
|
||||
case MASK_3F4_LFE: return CUBEB_LAYOUT_3F4_LFE;
|
||||
default: return CUBEB_LAYOUT_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
static void pulse_context_destroy(cubeb * ctx);
|
||||
static void pulse_destroy(cubeb * ctx);
|
||||
|
||||
|
@ -596,6 +704,23 @@ pulse_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
|
|||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
pulse_get_preferred_channel_layout(cubeb * ctx, cubeb_channel_layout * layout)
|
||||
{
|
||||
assert(ctx && layout);
|
||||
(void)ctx;
|
||||
|
||||
WRAP(pa_threaded_mainloop_lock)(ctx->mainloop);
|
||||
while (!ctx->default_sink_info) {
|
||||
WRAP(pa_threaded_mainloop_wait)(ctx->mainloop);
|
||||
}
|
||||
WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop);
|
||||
|
||||
*layout = channel_map_to_layout(&ctx->default_sink_info->channel_map);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
pulse_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * latency_frames)
|
||||
{
|
||||
|
@ -672,7 +797,8 @@ create_pa_stream(cubeb_stream * stm,
|
|||
cubeb_stream_params * stream_params,
|
||||
char const * stream_name)
|
||||
{
|
||||
assert(stm && stream_params);
|
||||
assert(stm && stream_params && stream_params->layout != CUBEB_LAYOUT_UNDEFINED &&
|
||||
CUBEB_CHANNEL_LAYOUT_MAPS[stream_params->layout].channels == stream_params->channels);
|
||||
*pa_stm = NULL;
|
||||
pa_sample_spec ss;
|
||||
ss.format = to_pulse_format(stream_params->format);
|
||||
|
@ -681,7 +807,10 @@ create_pa_stream(cubeb_stream * stm,
|
|||
ss.rate = stream_params->rate;
|
||||
ss.channels = stream_params->channels;
|
||||
|
||||
*pa_stm = WRAP(pa_stream_new)(stm->context->context, stream_name, &ss, NULL);
|
||||
pa_channel_map cm;
|
||||
layout_to_channel_map(stream_params->layout, &cm);
|
||||
|
||||
*pa_stm = WRAP(pa_stream_new)(stm->context->context, stream_name, &ss, &cm);
|
||||
return (*pa_stm == NULL) ? CUBEB_ERROR : CUBEB_OK;
|
||||
}
|
||||
|
||||
|
@ -1410,6 +1539,7 @@ static struct cubeb_ops const pulse_ops = {
|
|||
.get_max_channel_count = pulse_get_max_channel_count,
|
||||
.get_min_latency = pulse_get_min_latency,
|
||||
.get_preferred_sample_rate = pulse_get_preferred_sample_rate,
|
||||
.get_preferred_channel_layout = pulse_get_preferred_channel_layout,
|
||||
.enumerate_devices = pulse_enumerate_devices,
|
||||
.destroy = pulse_destroy,
|
||||
.stream_init = pulse_stream_init,
|
||||
|
|
|
@ -124,7 +124,6 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
|
|||
T * out_unprocessed = nullptr;
|
||||
long output_frames_before_processing = 0;
|
||||
|
||||
|
||||
/* fill directly the input buffer of the output processor to save a copy */
|
||||
output_frames_before_processing =
|
||||
output_processor->input_needed_for_output(output_frames_needed);
|
||||
|
@ -174,7 +173,6 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
|
|||
return (*input_frames_count) * (got / resampled_frame_count);
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename InputProcessor, typename OutputProcessor>
|
||||
long
|
||||
cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
|
||||
|
|
|
@ -366,6 +366,7 @@ static struct cubeb_ops const sndio_ops = {
|
|||
.get_max_channel_count = sndio_get_max_channel_count,
|
||||
.get_min_latency = sndio_get_min_latency,
|
||||
.get_preferred_sample_rate = sndio_get_preferred_sample_rate,
|
||||
.get_preferred_channel_layout = NULL,
|
||||
.enumerate_devices = NULL,
|
||||
.destroy = sndio_destroy,
|
||||
.stream_init = sndio_stream_init,
|
||||
|
|
|
@ -46,6 +46,63 @@ void PodZero(T * destination, size_t count)
|
|||
memset(destination, 0, count * sizeof(T));
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<typename T, typename Trait>
|
||||
void Copy(T * destination, const T * source, size_t count, Trait)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
destination[i] = source[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Copy(T * destination, const T * source, size_t count, std::true_type)
|
||||
{
|
||||
PodCopy(destination, source, count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows copying a number of elements from a `source` pointer to a
|
||||
* `destination` pointer, using `memcpy` if it is safe to do so, or a loop that
|
||||
* calls the constructors and destructors otherwise.
|
||||
*/
|
||||
template<typename T>
|
||||
void Copy(T * destination, const T * source, size_t count)
|
||||
{
|
||||
assert(destination && source);
|
||||
Copy(destination, source, count, typename std::is_trivial<T>::type());
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<typename T, typename Trait>
|
||||
void ConstructDefault(T * destination, size_t count, Trait)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
destination[i] = T();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ConstructDefault(T * destination,
|
||||
size_t count, std::true_type)
|
||||
{
|
||||
PodZero(destination, count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows zeroing (using memset) or default-constructing a number of
|
||||
* elements calling the constructors and destructors if necessary.
|
||||
*/
|
||||
template<typename T>
|
||||
void ConstructDefault(T * destination, size_t count)
|
||||
{
|
||||
assert(destination);
|
||||
ConstructDefault(destination, count,
|
||||
typename std::is_arithmetic<T>::type());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class auto_array
|
||||
{
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
// Explicitly define NTDDI_VERSION rather than letting the value be derived
|
||||
// from _WIN32_WINNT because we depend on values defined for XP SP2 and WS03
|
||||
// SP1.
|
||||
#define _WIN32_WINNT 0x0502
|
||||
#define NTDDI_VERSION 0x05020100
|
||||
#define NOMINMAX
|
||||
|
||||
#include <initguid.h>
|
||||
|
@ -27,6 +32,7 @@
|
|||
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "cubeb-internal.h"
|
||||
#include "cubeb_mixer.h"
|
||||
#include "cubeb_resampler.h"
|
||||
#include "cubeb_utils.h"
|
||||
|
||||
|
@ -198,12 +204,12 @@ struct cubeb_stream {
|
|||
/* Mixer pameters. We need to convert the input stream to this
|
||||
samplerate/channel layout, as WASAPI does not resample nor upmix
|
||||
itself. */
|
||||
cubeb_stream_params input_mix_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0 };
|
||||
cubeb_stream_params output_mix_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0 };
|
||||
cubeb_stream_params input_mix_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0, CUBEB_LAYOUT_UNDEFINED };
|
||||
cubeb_stream_params output_mix_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0, CUBEB_LAYOUT_UNDEFINED };
|
||||
/* Stream parameters. This is what the client requested,
|
||||
* and what will be presented in the callback. */
|
||||
cubeb_stream_params input_stream_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0 };
|
||||
cubeb_stream_params output_stream_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0 };
|
||||
cubeb_stream_params input_stream_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0, CUBEB_LAYOUT_UNDEFINED };
|
||||
cubeb_stream_params output_stream_params = { CUBEB_SAMPLE_FLOAT32NE, 0, 0, CUBEB_LAYOUT_UNDEFINED };
|
||||
/* The input and output device, or NULL for default. */
|
||||
std::unique_ptr<const wchar_t[]> input_device;
|
||||
std::unique_ptr<const wchar_t[]> output_device;
|
||||
|
@ -392,21 +398,89 @@ bool has_output(cubeb_stream * stm)
|
|||
return stm->output_stream_params.rate != 0;
|
||||
}
|
||||
|
||||
bool should_upmix(cubeb_stream_params & stream, cubeb_stream_params & mixer)
|
||||
{
|
||||
return mixer.channels > stream.channels;
|
||||
}
|
||||
|
||||
bool should_downmix(cubeb_stream_params & stream, cubeb_stream_params & mixer)
|
||||
{
|
||||
return mixer.channels < stream.channels;
|
||||
}
|
||||
|
||||
double stream_to_mix_samplerate_ratio(cubeb_stream_params & stream, cubeb_stream_params & mixer)
|
||||
{
|
||||
return double(stream.rate) / mixer.rate;
|
||||
}
|
||||
|
||||
/* Convert the channel layout into the corresponding KSAUDIO_CHANNEL_CONFIG.
|
||||
See more: https://msdn.microsoft.com/en-us/library/windows/hardware/ff537083(v=vs.85).aspx */
|
||||
#define MASK_DUAL_MONO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT)
|
||||
#define MASK_DUAL_MONO_LFE (MASK_DUAL_MONO | SPEAKER_LOW_FREQUENCY)
|
||||
#define MASK_MONO (KSAUDIO_SPEAKER_MONO)
|
||||
#define MASK_MONO_LFE (MASK_MONO | SPEAKER_LOW_FREQUENCY)
|
||||
#define MASK_STEREO (KSAUDIO_SPEAKER_STEREO)
|
||||
#define MASK_STEREO_LFE (MASK_STEREO | SPEAKER_LOW_FREQUENCY)
|
||||
#define MASK_3F (MASK_STEREO | SPEAKER_FRONT_CENTER)
|
||||
#define MASK_3F_LFE (MASK_3F | SPEAKER_LOW_FREQUENCY)
|
||||
#define MASK_2F1 (MASK_STEREO | SPEAKER_BACK_CENTER)
|
||||
#define MASK_2F1_LFE (MASK_2F1 | SPEAKER_LOW_FREQUENCY)
|
||||
#define MASK_3F1 (KSAUDIO_SPEAKER_SURROUND)
|
||||
#define MASK_3F1_LFE (MASK_3F1 | SPEAKER_LOW_FREQUENCY)
|
||||
#define MASK_2F2 (MASK_STEREO | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT)
|
||||
#define MASK_2F2_LFE (MASK_2F2 | SPEAKER_LOW_FREQUENCY)
|
||||
#define MASK_3F2 (MASK_3F | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT)
|
||||
#define MASK_3F2_LFE (KSAUDIO_SPEAKER_5POINT1_SURROUND)
|
||||
#define MASK_3F3R_LFE (MASK_3F2_LFE | SPEAKER_BACK_CENTER)
|
||||
#define MASK_3F4_LFE (KSAUDIO_SPEAKER_7POINT1_SURROUND)
|
||||
|
||||
static DWORD
|
||||
channel_layout_to_mask(cubeb_channel_layout layout)
|
||||
{
|
||||
XASSERT(layout > CUBEB_LAYOUT_UNDEFINED && layout < CUBEB_LAYOUT_MAX &&
|
||||
"This mask conversion is not allowed.");
|
||||
|
||||
// This variable may be used for multiple times, so we should avoid to
|
||||
// allocate it in stack, or it will be created and removed repeatedly.
|
||||
// Use static to allocate this local variable in data space instead of stack.
|
||||
static DWORD map[CUBEB_LAYOUT_MAX] = {
|
||||
0, // CUBEB_LAYOUT_UNDEFINED (this won't be used.)
|
||||
MASK_DUAL_MONO, // CUBEB_LAYOUT_DUAL_MONO
|
||||
MASK_DUAL_MONO_LFE, // CUBEB_LAYOUT_DUAL_MONO_LFE
|
||||
MASK_MONO, // CUBEB_LAYOUT_MONO
|
||||
MASK_MONO_LFE, // CUBEB_LAYOUT_MONO_LFE
|
||||
MASK_STEREO, // CUBEB_LAYOUT_STEREO
|
||||
MASK_STEREO_LFE, // CUBEB_LAYOUT_STEREO_LFE
|
||||
MASK_3F, // CUBEB_LAYOUT_3F
|
||||
MASK_3F_LFE, // CUBEB_LAYOUT_3F_LFE
|
||||
MASK_2F1, // CUBEB_LAYOUT_2F1
|
||||
MASK_2F1_LFE, // CUBEB_LAYOUT_2F1_LFE
|
||||
MASK_3F1, // CUBEB_LAYOUT_3F1
|
||||
MASK_3F1_LFE, // CUBEB_LAYOUT_3F1_LFE
|
||||
MASK_2F2, // CUBEB_LAYOUT_2F2
|
||||
MASK_2F2_LFE, // CUBEB_LAYOUT_2F2_LFE
|
||||
MASK_3F2, // CUBEB_LAYOUT_3F2
|
||||
MASK_3F2_LFE, // CUBEB_LAYOUT_3F2_LFE
|
||||
MASK_3F3R_LFE, // CUBEB_LAYOUT_3F3R_LFE
|
||||
MASK_3F4_LFE, // CUBEB_LAYOUT_3F4_LFE
|
||||
};
|
||||
return map[layout];
|
||||
}
|
||||
|
||||
cubeb_channel_layout
|
||||
mask_to_channel_layout(DWORD mask)
|
||||
{
|
||||
switch (mask) {
|
||||
// MASK_DUAL_MONO(_LFE) is same as STEREO(_LFE), so we skip it.
|
||||
case MASK_MONO: return CUBEB_LAYOUT_MONO;
|
||||
case MASK_MONO_LFE: return CUBEB_LAYOUT_MONO_LFE;
|
||||
case MASK_STEREO: return CUBEB_LAYOUT_STEREO;
|
||||
case MASK_STEREO_LFE: return CUBEB_LAYOUT_STEREO_LFE;
|
||||
case MASK_3F: return CUBEB_LAYOUT_3F;
|
||||
case MASK_3F_LFE: return CUBEB_LAYOUT_3F_LFE;
|
||||
case MASK_2F1: return CUBEB_LAYOUT_2F1;
|
||||
case MASK_2F1_LFE: return CUBEB_LAYOUT_2F1_LFE;
|
||||
case MASK_3F1: return CUBEB_LAYOUT_3F1;
|
||||
case MASK_3F1_LFE: return CUBEB_LAYOUT_3F1_LFE;
|
||||
case MASK_2F2: return CUBEB_LAYOUT_2F2;
|
||||
case MASK_2F2_LFE: return CUBEB_LAYOUT_2F2_LFE;
|
||||
case MASK_3F2: return CUBEB_LAYOUT_3F2;
|
||||
case MASK_3F2_LFE: return CUBEB_LAYOUT_3F2_LFE;
|
||||
case MASK_3F3R_LFE: return CUBEB_LAYOUT_3F3R_LFE;
|
||||
case MASK_3F4_LFE: return CUBEB_LAYOUT_3F4_LFE;
|
||||
default: return CUBEB_LAYOUT_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
get_rate(cubeb_stream * stm)
|
||||
|
@ -439,71 +513,13 @@ frames_to_hns(cubeb_stream * stm, uint32_t frames)
|
|||
return frames * 1000 / get_rate(stm);
|
||||
}
|
||||
|
||||
/* Upmix function, copies a mono channel into L and R */
|
||||
template<typename T>
|
||||
void
|
||||
mono_to_stereo(T * in, long insamples, T * out, int32_t out_channels)
|
||||
{
|
||||
for (int i = 0, j = 0; i < insamples; ++i, j += out_channels) {
|
||||
out[j] = out[j + 1] = in[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
upmix(T * in, long inframes, T * out, int32_t in_channels, int32_t out_channels)
|
||||
{
|
||||
XASSERT(out_channels >= in_channels && in_channels > 0);
|
||||
|
||||
/* Either way, if we have 2 or more channels, the first two are L and R. */
|
||||
/* If we are playing a mono stream over stereo speakers, copy the data over. */
|
||||
if (in_channels == 1 && out_channels >= 2) {
|
||||
mono_to_stereo(in, inframes, out, out_channels);
|
||||
} else {
|
||||
/* Copy through. */
|
||||
for (int i = 0, o = 0; i < inframes * in_channels;
|
||||
i += in_channels, o += out_channels) {
|
||||
for (int j = 0; j < in_channels; ++j) {
|
||||
out[o + j] = in[i + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if more channels. */
|
||||
if (out_channels <= 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Put silence in remaining channels. */
|
||||
for (long i = 0, o = 0; i < inframes; ++i, o += out_channels) {
|
||||
for (int j = 2; j < out_channels; ++j) {
|
||||
out[o + j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
downmix(T * in, long inframes, T * out, int32_t in_channels, int32_t out_channels)
|
||||
{
|
||||
XASSERT(in_channels >= out_channels);
|
||||
/* We could use a downmix matrix here, applying mixing weight based on the
|
||||
channel, but directsound and winmm simply drop the channels that cannot be
|
||||
rendered by the hardware, so we do the same for consistency. */
|
||||
long out_index = 0;
|
||||
for (long i = 0; i < inframes * in_channels; i += in_channels) {
|
||||
for (int j = 0; j < out_channels; ++j) {
|
||||
out[out_index + j] = in[i + j];
|
||||
}
|
||||
out_index += out_channels;
|
||||
}
|
||||
}
|
||||
|
||||
/* This returns the size of a frame in the stream, before the eventual upmix
|
||||
occurs. */
|
||||
static size_t
|
||||
frames_to_bytes_before_mix(cubeb_stream * stm, size_t frames)
|
||||
{
|
||||
// This is called only when we has a output client.
|
||||
XASSERT(has_output(stm));
|
||||
size_t stream_frame_size = stm->output_stream_params.channels * sizeof(float);
|
||||
return stream_frame_size * frames;
|
||||
}
|
||||
|
@ -519,8 +535,8 @@ refill(cubeb_stream * stm, float * input_buffer, long input_frames_count,
|
|||
avoid a copy. */
|
||||
float * dest = nullptr;
|
||||
if (has_output(stm)) {
|
||||
if (should_upmix(stm->output_stream_params, stm->output_mix_params) ||
|
||||
should_downmix(stm->output_stream_params, stm->output_mix_params)) {
|
||||
if (cubeb_should_upmix(&stm->output_stream_params, &stm->output_mix_params) ||
|
||||
cubeb_should_downmix(&stm->output_stream_params, &stm->output_mix_params)) {
|
||||
dest = stm->mix_buffer.data();
|
||||
} else {
|
||||
dest = output_buffer;
|
||||
|
@ -551,12 +567,13 @@ refill(cubeb_stream * stm, float * input_buffer, long input_frames_count,
|
|||
XASSERT(out_frames == output_frames_needed || stm->draining || !has_output(stm));
|
||||
|
||||
if (has_output(stm)) {
|
||||
if (should_upmix(stm->output_stream_params, stm->output_mix_params)) {
|
||||
upmix(dest, out_frames, output_buffer,
|
||||
stm->output_stream_params.channels, stm->output_mix_params.channels);
|
||||
} else if (should_downmix(stm->output_stream_params, stm->output_mix_params)) {
|
||||
downmix(dest, out_frames, output_buffer,
|
||||
stm->output_stream_params.channels, stm->output_mix_params.channels);
|
||||
if (cubeb_should_upmix(&stm->output_stream_params, &stm->output_mix_params)) {
|
||||
cubeb_upmix_float(dest, out_frames, output_buffer,
|
||||
stm->output_stream_params.channels, stm->output_mix_params.channels);
|
||||
} else if (cubeb_should_downmix(&stm->output_stream_params, &stm->output_mix_params)) {
|
||||
cubeb_downmix_float(dest, out_frames, output_buffer,
|
||||
stm->output_stream_params.channels, stm->output_mix_params.channels,
|
||||
stm->output_stream_params.layout, stm->output_mix_params.layout);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -615,23 +632,25 @@ bool get_input_buffer(cubeb_stream * stm)
|
|||
LOG("insert silence: ps=%u", packet_size);
|
||||
stm->linear_input_buffer.push_silence(packet_size * stm->input_stream_params.channels);
|
||||
} else {
|
||||
if (should_upmix(stm->input_mix_params, stm->input_stream_params)) {
|
||||
if (cubeb_should_upmix(&stm->input_mix_params, &stm->input_stream_params)) {
|
||||
bool ok = stm->linear_input_buffer.reserve(stm->linear_input_buffer.length() +
|
||||
packet_size * stm->input_stream_params.channels);
|
||||
XASSERT(ok);
|
||||
upmix(reinterpret_cast<float*>(input_packet), packet_size,
|
||||
stm->linear_input_buffer.data() + stm->linear_input_buffer.length(),
|
||||
stm->input_mix_params.channels,
|
||||
stm->input_stream_params.channels);
|
||||
cubeb_upmix_float(reinterpret_cast<float*>(input_packet), packet_size,
|
||||
stm->linear_input_buffer.data() + stm->linear_input_buffer.length(),
|
||||
stm->input_mix_params.channels,
|
||||
stm->input_stream_params.channels);
|
||||
stm->linear_input_buffer.set_length(stm->linear_input_buffer.length() + packet_size * stm->input_stream_params.channels);
|
||||
} else if (should_downmix(stm->input_mix_params, stm->input_stream_params)) {
|
||||
} else if (cubeb_should_downmix(&stm->input_mix_params, &stm->input_stream_params)) {
|
||||
bool ok = stm->linear_input_buffer.reserve(stm->linear_input_buffer.length() +
|
||||
packet_size * stm->input_stream_params.channels);
|
||||
XASSERT(ok);
|
||||
downmix(reinterpret_cast<float*>(input_packet), packet_size,
|
||||
stm->linear_input_buffer.data() + stm->linear_input_buffer.length(),
|
||||
stm->input_mix_params.channels,
|
||||
stm->input_stream_params.channels);
|
||||
cubeb_downmix_float(reinterpret_cast<float*>(input_packet), packet_size,
|
||||
stm->linear_input_buffer.data() + stm->linear_input_buffer.length(),
|
||||
stm->input_mix_params.channels,
|
||||
stm->input_stream_params.channels,
|
||||
stm->input_mix_params.layout,
|
||||
stm->input_stream_params.layout);
|
||||
stm->linear_input_buffer.set_length(stm->linear_input_buffer.length() + packet_size * stm->input_stream_params.channels);
|
||||
} else {
|
||||
stm->linear_input_buffer.push(reinterpret_cast<float*>(input_packet),
|
||||
|
@ -781,7 +800,8 @@ refill_callback_input(cubeb_stream * stm)
|
|||
nullptr,
|
||||
0);
|
||||
|
||||
consumed_all_buffer = read == stm->linear_input_buffer.length();
|
||||
XASSERT(read >= 0);
|
||||
consumed_all_buffer = (unsigned long) read == stm->linear_input_buffer.length();
|
||||
|
||||
stm->linear_input_buffer.clear();
|
||||
|
||||
|
@ -817,7 +837,7 @@ refill_callback_output(cubeb_stream * stm)
|
|||
output_frames, got);
|
||||
|
||||
XASSERT(got >= 0);
|
||||
XASSERT(got == output_frames || stm->draining);
|
||||
XASSERT((unsigned long) got == output_frames || stm->draining);
|
||||
|
||||
hr = stm->render_client->ReleaseBuffer(got, 0);
|
||||
if (FAILED(hr)) {
|
||||
|
@ -825,7 +845,7 @@ refill_callback_output(cubeb_stream * stm)
|
|||
return false;
|
||||
}
|
||||
|
||||
return got == output_frames || stm->draining;
|
||||
return (unsigned long) got == output_frames || stm->draining;
|
||||
}
|
||||
|
||||
static unsigned int __stdcall
|
||||
|
@ -860,7 +880,6 @@ wasapi_stream_render_loop(LPVOID stream)
|
|||
LOG("Unable to use mmcss to bump the render thread priority: %lx", GetLastError());
|
||||
}
|
||||
|
||||
|
||||
/* WaitForMultipleObjects timeout can trigger in cases where we don't want to
|
||||
treat it as a timeout, such as across a system sleep/wake cycle. Trigger
|
||||
the timeout error handling only when the timeout_limit is reached, which is
|
||||
|
@ -1211,13 +1230,18 @@ bool stop_and_join_render_thread(cubeb_stream * stm)
|
|||
rv = false;
|
||||
}
|
||||
|
||||
LOG("Closing thread.");
|
||||
|
||||
CloseHandle(stm->thread);
|
||||
stm->thread = NULL;
|
||||
// Only attempts to close and null out the thread and event if the
|
||||
// WaitForSingleObject above succeeded, so that calling this function again
|
||||
// attemps to clean up the thread and event each time.
|
||||
if (rv) {
|
||||
LOG("Closing thread.");
|
||||
CloseHandle(stm->thread);
|
||||
stm->thread = NULL;
|
||||
|
||||
CloseHandle(stm->shutdown_event);
|
||||
stm->shutdown_event = 0;
|
||||
CloseHandle(stm->shutdown_event);
|
||||
stm->shutdown_event = 0;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -1359,6 +1383,44 @@ wasapi_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
|
|||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int
|
||||
wasapi_get_preferred_channel_layout(cubeb * context, cubeb_channel_layout * layout)
|
||||
{
|
||||
HRESULT hr;
|
||||
auto_com com;
|
||||
if (!com.ok()) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
com_ptr<IMMDevice> device;
|
||||
hr = get_default_endpoint(device, eRender);
|
||||
if (FAILED(hr)) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
com_ptr<IAudioClient> client;
|
||||
hr = device->Activate(__uuidof(IAudioClient),
|
||||
CLSCTX_INPROC_SERVER,
|
||||
NULL, client.receive_vpp());
|
||||
if (FAILED(hr)) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
WAVEFORMATEX * tmp = nullptr;
|
||||
hr = client->GetMixFormat(&tmp);
|
||||
if (FAILED(hr)) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
com_heap_ptr<WAVEFORMATEX> mix_format(tmp);
|
||||
|
||||
WAVEFORMATEXTENSIBLE * format_pcm = reinterpret_cast<WAVEFORMATEXTENSIBLE *>(mix_format.get());
|
||||
*layout = mask_to_channel_layout(format_pcm->dwChannelMask);
|
||||
|
||||
LOG("Preferred channel layout: %s", CUBEB_CHANNEL_LAYOUT_MAPS[*layout].name);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
void wasapi_stream_destroy(cubeb_stream * stm);
|
||||
|
||||
/* Based on the mix format and the stream format, try to find a way to play
|
||||
|
@ -1366,12 +1428,7 @@ void wasapi_stream_destroy(cubeb_stream * stm);
|
|||
static void
|
||||
handle_channel_layout(cubeb_stream * stm, com_heap_ptr<WAVEFORMATEX> & mix_format, const cubeb_stream_params * stream_params)
|
||||
{
|
||||
/* Common case: the hardware is stereo. Up-mixing and down-mixing will be
|
||||
handled in the callback. */
|
||||
if (mix_format->nChannels <= 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
XASSERT(stream_params->layout != CUBEB_LAYOUT_UNDEFINED);
|
||||
/* The docs say that GetMixFormat is always of type WAVEFORMATEXTENSIBLE [1],
|
||||
so the reinterpret_cast below should be safe. In practice, this is not
|
||||
true, and we just want to bail out and let the rest of the code find a good
|
||||
|
@ -1386,19 +1443,10 @@ handle_channel_layout(cubeb_stream * stm, com_heap_ptr<WAVEFORMATEX> & mix_form
|
|||
/* Stash a copy of the original mix format in case we need to restore it later. */
|
||||
WAVEFORMATEXTENSIBLE hw_mix_format = *format_pcm;
|
||||
|
||||
/* The hardware is in surround mode, we want to only use front left and front
|
||||
right. Try that, and check if it works. */
|
||||
switch (stream_params->channels) {
|
||||
case 1: /* Mono */
|
||||
format_pcm->dwChannelMask = KSAUDIO_SPEAKER_MONO;
|
||||
break;
|
||||
case 2: /* Stereo */
|
||||
format_pcm->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
|
||||
break;
|
||||
default:
|
||||
XASSERT(false && "Channel layout not supported.");
|
||||
break;
|
||||
}
|
||||
/* Get the channel mask by the channel layout.
|
||||
If the layout is not supported, we will get a closest settings below. */
|
||||
format_pcm->dwChannelMask = channel_layout_to_mask(stream_params->layout);
|
||||
|
||||
mix_format->nChannels = stream_params->channels;
|
||||
mix_format->nBlockAlign = mix_format->wBitsPerSample * mix_format->nChannels / 8;
|
||||
mix_format->nAvgBytesPerSec = mix_format->nSamplesPerSec * mix_format->nBlockAlign;
|
||||
|
@ -1499,16 +1547,39 @@ int setup_wasapi_stream_one_side(cubeb_stream * stm,
|
|||
}
|
||||
com_heap_ptr<WAVEFORMATEX> mix_format(tmp);
|
||||
|
||||
handle_channel_layout(stm, mix_format, stream_params);
|
||||
/* Set channel layout only when there're more than two channels. Otherwise,
|
||||
* use the default setting retrieved from the stream format of the audio
|
||||
* engine's internal processing by GetMixFormat. */
|
||||
if (mix_format->nChannels > 2) {
|
||||
/* Currently, we only support mono and stereo for capture stream. */
|
||||
if (direction == eCapture) {
|
||||
XASSERT(false && "Multichannel recording is not supported.");
|
||||
}
|
||||
|
||||
handle_channel_layout(stm, mix_format, stream_params);
|
||||
}
|
||||
|
||||
/* Shared mode WASAPI always supports float32 sample format, so this
|
||||
* is safe. */
|
||||
mix_params->format = CUBEB_SAMPLE_FLOAT32NE;
|
||||
mix_params->rate = mix_format->nSamplesPerSec;
|
||||
mix_params->channels = mix_format->nChannels;
|
||||
LOG("Setup requested=[f=%d r=%u c=%u] mix=[f=%d r=%u c=%u]",
|
||||
WAVEFORMATEXTENSIBLE * format_pcm = reinterpret_cast<WAVEFORMATEXTENSIBLE *>(mix_format.get());
|
||||
mix_params->layout = mask_to_channel_layout(format_pcm->dwChannelMask);
|
||||
if (mix_params->layout == CUBEB_LAYOUT_UNDEFINED) {
|
||||
LOG("Output using undefined layout!\n");
|
||||
} else if (mix_format->nChannels != CUBEB_CHANNEL_LAYOUT_MAPS[mix_params->layout].channels) {
|
||||
// The CUBEB_CHANNEL_LAYOUT_MAPS[mix_params->layout].channels may be
|
||||
// different from the mix_params->channels. 6 channel ouput with stereo
|
||||
// layout is acceptable in Windows. If this happens, it should not downmix
|
||||
// audio according to layout.
|
||||
LOG("Channel count is different from the layout standard!\n");
|
||||
}
|
||||
LOG("Setup requested=[f=%d r=%u c=%u l=%s] mix=[f=%d r=%u c=%u l=%s]",
|
||||
stream_params->format, stream_params->rate, stream_params->channels,
|
||||
mix_params->format, mix_params->rate, mix_params->channels);
|
||||
CUBEB_CHANNEL_LAYOUT_MAPS[stream_params->layout].name,
|
||||
mix_params->format, mix_params->rate, mix_params->channels,
|
||||
CUBEB_CHANNEL_LAYOUT_MAPS[mix_params->layout].name);
|
||||
|
||||
hr = audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED,
|
||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK |
|
||||
|
@ -1530,8 +1601,8 @@ int setup_wasapi_stream_one_side(cubeb_stream * stm,
|
|||
}
|
||||
// Input is up/down mixed when depacketized in get_input_buffer.
|
||||
if (has_output(stm) &&
|
||||
(should_upmix(*stream_params, *mix_params) ||
|
||||
should_downmix(*stream_params, *mix_params))) {
|
||||
(cubeb_should_upmix(stream_params, mix_params) ||
|
||||
cubeb_should_downmix(stream_params, mix_params))) {
|
||||
stm->mix_buffer.resize(frames_to_bytes_before_mix(stm, *buffer_frame_count));
|
||||
}
|
||||
|
||||
|
@ -1712,10 +1783,14 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream,
|
|||
if (input_stream_params) {
|
||||
stm->input_stream_params = *input_stream_params;
|
||||
stm->input_device = utf8_to_wstr(reinterpret_cast<char const *>(input_device));
|
||||
// Make sure the layout matches the channel count.
|
||||
XASSERT(stm->input_stream_params.channels == CUBEB_CHANNEL_LAYOUT_MAPS[stm->input_stream_params.layout].channels);
|
||||
}
|
||||
if (output_stream_params) {
|
||||
stm->output_stream_params = *output_stream_params;
|
||||
stm->output_device = utf8_to_wstr(reinterpret_cast<char const *>(output_device));
|
||||
// Make sure the layout matches the channel count.
|
||||
XASSERT(stm->output_stream_params.channels == CUBEB_CHANNEL_LAYOUT_MAPS[stm->output_stream_params.layout].channels);
|
||||
}
|
||||
|
||||
stm->latency = latency_frames;
|
||||
|
@ -1921,7 +1996,6 @@ int wasapi_stream_stop(cubeb_stream * stm)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
|
||||
}
|
||||
|
||||
|
@ -2252,6 +2326,7 @@ cubeb_ops const wasapi_ops = {
|
|||
/*.get_max_channel_count =*/ wasapi_get_max_channel_count,
|
||||
/*.get_min_latency =*/ wasapi_get_min_latency,
|
||||
/*.get_preferred_sample_rate =*/ wasapi_get_preferred_sample_rate,
|
||||
/*.get_preferred_channel_layout =*/ wasapi_get_preferred_channel_layout,
|
||||
/*.enumerate_devices =*/ wasapi_enumerate_devices,
|
||||
/*.destroy =*/ wasapi_destroy,
|
||||
/*.stream_init =*/ wasapi_stream_init,
|
||||
|
|
|
@ -512,7 +512,6 @@ winmm_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n
|
|||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < NBUFS; ++i) {
|
||||
WAVEHDR * hdr = &stm->buffers[i];
|
||||
|
||||
|
@ -769,7 +768,6 @@ winmm_calculate_device_rate(cubeb_device_info * info, DWORD formats)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#define MM_S16_MASK (WAVE_FORMAT_1M16 | WAVE_FORMAT_1S16 | WAVE_FORMAT_2M16 | WAVE_FORMAT_2S16 | WAVE_FORMAT_4M16 | \
|
||||
WAVE_FORMAT_4S16 | WAVE_FORMAT_48M16 | WAVE_FORMAT_48S16 | WAVE_FORMAT_96M16 | WAVE_FORMAT_96S16)
|
||||
static int
|
||||
|
@ -1050,6 +1048,7 @@ static struct cubeb_ops const winmm_ops = {
|
|||
/*.get_max_channel_count=*/ winmm_get_max_channel_count,
|
||||
/*.get_min_latency=*/ winmm_get_min_latency,
|
||||
/*.get_preferred_sample_rate =*/ winmm_get_preferred_sample_rate,
|
||||
/*.get_preferred_channel_layout =*/ NULL,
|
||||
/*.enumerate_devices =*/ winmm_enumerate_devices,
|
||||
/*.destroy =*/ winmm_destroy,
|
||||
/*.stream_init =*/ winmm_stream_init,
|
||||
|
|
|
@ -10,6 +10,7 @@ Library('cubeb')
|
|||
|
||||
SOURCES += [
|
||||
'cubeb.c',
|
||||
'cubeb_mixer.cpp',
|
||||
'cubeb_panner.cpp'
|
||||
]
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ cp $1/src/cubeb_utils_unix.h src
|
|||
cp $1/src/cubeb_utils_win.h src
|
||||
cp $1/src/cubeb_wasapi.cpp src
|
||||
cp $1/src/cubeb_winmm.c src
|
||||
cp $1/src/cubeb_mixer.h src
|
||||
cp $1/src/cubeb_mixer.cpp src
|
||||
cp $1/test/common.h gtest
|
||||
cp $1/test/test_audio.cpp gtest
|
||||
cp $1/test/test_devices.cpp gtest
|
||||
|
@ -42,6 +44,7 @@ cp $1/test/test_ring_array.cpp gtest
|
|||
cp $1/test/test_sanity.cpp gtest
|
||||
cp $1/test/test_tone.cpp gtest
|
||||
cp $1/test/test_utils.cpp gtest
|
||||
cp $1/test/test_mixer.cpp gtest
|
||||
|
||||
if [ -d $1/.git ]; then
|
||||
rev=$(cd $1 && git rev-parse --verify HEAD)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICxTCCAa+gAwIBAgIUQy+m6w0ZtMTfbmtELQQz8zwqCAowCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICxTCCAa+gAwIBAgIUL5zykZEc2ro5d6th43aWGfm735cwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMA0xCzAJBgNVBAMMAmNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu
|
||||
Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO
|
||||
|
@ -8,10 +8,10 @@ Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO
|
|||
qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt
|
||||
HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx
|
||||
uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1Ud
|
||||
DwQEAwIBBjALBgkqhkiG9w0BAQsDggEBAJQcekrdR+S6U0I3owUQxVOoUJMzHdTj
|
||||
u562Ra7cOiJQwe1OQZbvo6rQkQWPrpuDOGpwwr1+HBMGb8mjUqeFo5wIinU003TC
|
||||
UYYEpDCbPwXOKDkDUukKd1aO4wpJc/v8YIiCz7aCRj9HQ3L5YO5JsgMNSCXKKoUm
|
||||
ILcz2V+IQZ6lePzFfd2aO3zLMDPwEOyujYYtQnBVZIT4F/x/6nU8E6bkbDSGPjQW
|
||||
CSVhwa0YQ9lCRSM6e//wGry4i8X8718t1V+Nqh7y6u7UlOrXbNEA4pR6mvJsqPhF
|
||||
Mj82We4OGNBxXbyuGJObQgLBfmRuwKQT9SNtKWEifiaTw8apT/fBagc=
|
||||
DwQEAwIBBjALBgkqhkiG9w0BAQsDggEBAHPYBjNnv//Ssc8Elepb8SWIXRdahKbL
|
||||
/dcPoMR+7yhJVaelUaxdwUytJWJAGdkkuv+P+G4b82RVYEXT+9k1S/aAfByFyR9q
|
||||
vS7POfdy/ZPfGTXltlnmYX/84a6QeYQa4Nl4JpIOXBCesLxmErBhczka6D26iqsz
|
||||
GeseKRSjVPgF3mXc2CRGZnTDRhUmd7wOABLmj7GtuFvOm96363M3IUByMohvoj1G
|
||||
dic3s5D0seXwTKnEc5B27lJt7Q0oIXEldL+UW8Mo1hfGWQeXzqTZbpOVLnVWvHBH
|
||||
H8yYs5hyH01qFJZbztJ1JJ3F2NpYLlr4P5I6fW2e9w5MG/VMQRU3wzQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICxDCCAa6gAwIBAgIUdey1Pi3nj8syGBLqTY30bbsak7swCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICxDCCAa6gAwIBAgIUSbYQoLY1s6wWqgbKhxQZ3XME7ukwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMBIxEDAOBgNVBAMMB2NvZGUtZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9
|
||||
sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5
|
||||
|
@ -8,10 +8,10 @@ TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7
|
|||
xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd
|
||||
tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l
|
||||
8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsG
|
||||
AQUFBwMDMAsGCSqGSIb3DQEBCwOCAQEAubYFMnDLOK8/99OLWeejdD6HQ8Qg2W4u
|
||||
7I9hZySo+g0w2U6jvtgSTvUfN/Zk33fSu90yOnWg1v+6tvd/jdwxfooVfz7zNWa9
|
||||
i6/oSY/0THBhX9bf9b0wHmZLnuhS7AwG6BCbqulQ3xJxCSWUieFTyoMl4UnW64md
|
||||
QBI+ZkLkS7O71pARnw0SdE4nxO1J8fLPi/7nYHiGfebqcoBC/AUwMM/Zni9KFkgy
|
||||
/uQRXUylNAgAByIdG6vS4ULgTKh34FS08Ff7/cWZppe9eUogLLQ+J2cyPupN8LYd
|
||||
hWC1mCbgCX3QqHiHg6ACX05Zc3YFW80ddlczDVNpM09g1GSGYpllng==
|
||||
AQUFBwMDMAsGCSqGSIb3DQEBCwOCAQEAV69uBbyc/d1eBdZlT7eAw4onQzkdndd8
|
||||
kEXdmP3hd+jJm1+/F733IflLLqE5mmUL9l7q7EJ+TgdZa19T6JHEaVjdJcIuwJO/
|
||||
kKSJXXqADQXoxHOZADDWjAFStiR3xd78BzYfuUANgozG6hq7QuVh0cYBx/8Q9gx/
|
||||
pGtuCJiN0d2Mknu0SoQzIZlXTuqmnFj7G/88O5Yh5MaFZxbvIJJSIWQoS396GrI6
|
||||
yXAdqHNoVM9mwwaMcnG5QeeKSIPuvEkZncQsxFc0zqIjeOVx/zEx2Bocx71dLuVB
|
||||
fqrIrAXLpwparoSxLzNqq8UgtXF8NQOuAcUu7ok0r1VbdMbSZHZ3Gg==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICvjCCAaigAwIBAgIUMUZEIRRo2v0demTGW3vuRccAgCMwCwYJKoZIhvcNAQEL
|
||||
MBUxEzARBgNVBAMMCmV4cGlyZWQtY2EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3
|
||||
MDIwNDAwMDAwMFowHTEbMBkGA1UEAwwSZWUtZnJvbS1leHBpcmVkLWNhMIIBIjAN
|
||||
MIICvjCCAaigAwIBAgIUGzSP8KEmmRm3sIPiyQW35sazlHEwCwYJKoZIhvcNAQEL
|
||||
MBUxEzARBgNVBAMMCmV4cGlyZWQtY2EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4
|
||||
MDIwNTAwMDAwMFowHTEbMBkGA1UEAwwSZWUtZnJvbS1leHBpcmVkLWNhMIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq
|
||||
5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc
|
||||
An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39
|
||||
ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk
|
||||
zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u
|
||||
JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB
|
||||
MAsGCSqGSIb3DQEBCwOCAQEABbpfCUwzbTCDWWwBqaY8+3q3PjeQK/QdyI4HSX5C
|
||||
+dp7LJF+x/24xArqKf8HTuhndprUvlJOFkojK1CLaece7yC1fh/viFZ6NLoTPNXU
|
||||
cmdEHsrzO4LTOY/eeR9ml7Rx26B50Wva01SyXkW9TZbPGPQysCgD31XkxmzTAG9t
|
||||
M5kp+XplMd/UEjkNQaXD0lzm3lJ+3n2U6xMmDc+8us0l6X8yBmjjywBWTSX+U83a
|
||||
eZXMpU40Y4ZHyNqfALGZUG22trd+68YVvK7jmnbk9fu/FZkjh0qiPlAUJXg0OybW
|
||||
YHerQxXuf+5+ftPTDkzyPY9txQGFoqY8k3zVQNw33wFzGQ==
|
||||
MAsGCSqGSIb3DQEBCwOCAQEAZ6Nrb/1fit8cALMhcbmuZ5kd3J34d0o9p3g3E7m7
|
||||
8RsTbYLA4xp9UmSzpO/10x9q4TUZ8jxW1dotoCVf7OqYYxQewrU2x3qoxKvP/Fvf
|
||||
8ssWSIang91w+app+fv7QYDySymT6DJMLWyCmxyhaFjYnmr67GKldcgK9hbyjfDB
|
||||
Rj382czI/HMSvw/vCB6rRKchzr5hsDGl+YN0MMI4M7/3b5wvMUmxlXqKu1VlslDZ
|
||||
8Ez6ONuMdPJD3aQZMxmEph05pEMvhjFhLh+0n7kfLR+9n0D7IR9paVc6LgHLLxsP
|
||||
ENoZLGOwJYNdAwwkd6fIa9E6KCpaRgyvWslm+iFCg3XxoA==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICwjCCAaygAwIBAgIUTUHM6wHTfIkC0P4Z9VRrPJV6O6IwCwYJKoZIhvcNAQEL
|
||||
MBcxFTATBgNVBAMMDHVudHJ1c3RlZC1jYTAiGA8yMDE0MTEyNzAwMDAwMFoYDzIw
|
||||
MTcwMjA0MDAwMDAwWjAfMR0wGwYDVQQDDBRlZS1mcm9tLXVudHJ1c3RlZC1jYTCC
|
||||
MIICwjCCAaygAwIBAgIUI/4Y+KSEZo8YGQK6Ptrdmev5FO0wCwYJKoZIhvcNAQEL
|
||||
MBcxFTATBgNVBAMMDHVudHJ1c3RlZC1jYTAiGA8yMDE1MTEyODAwMDAwMFoYDzIw
|
||||
MTgwMjA1MDAwMDAwWjAfMR0wGwYDVQQDDBRlZS1mcm9tLXVudHJ1c3RlZC1jYTCC
|
||||
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9
|
||||
PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3
|
||||
HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg
|
||||
Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7
|
||||
EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK
|
||||
lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C
|
||||
AwEAATALBgkqhkiG9w0BAQsDggEBAJlRi+i7+kPXxfx6If69aQMsAIYwBXhbeHJr
|
||||
TfaljltazfCirKB1hDb/pTYmSFMWDO+C9GIRBBKWR4+rR6D8n1qiJOJqe+QHtQam
|
||||
BPi8xMTHEkNVTEax+Ux2im21BPUU8xFzCta/STMCt2E+6g832JX1XxLxRlp631Vn
|
||||
pF9MFZU9HQqW4z8YBPPKE4ny9eBOGH/PzYHETL5AgJn1K5iRFZjA94iwqsHvJ/6v
|
||||
AY1b5hw1slwem9ZWYcoUUl3YAV7sF3pIbakrRSjU3HEfGcDUDOePrBZekJhICwK4
|
||||
xs2cqEX0FLZqsNiS7rpfRZXt4Ufl6V3G8MEO010lICk9ZuHr9vc=
|
||||
AwEAATALBgkqhkiG9w0BAQsDggEBAJqsDDoJqxrmV4Mlt815HmJwhr/SuYhPwhoQ
|
||||
RyU56Ci5kY/8fYa3F1uxSrpzuiYBX4bq6g8keXmltPZGN9gexPP2QJDAecNt0NKW
|
||||
+04ZKSiz6Tbu+MEyBaXCINDKaAHVPRnbMWR1eCyHzYpZRKZW2Sb2NinWGebzq0mI
|
||||
wt5l7veMkL5ZbeYF8u8bNFsdvhl1PM7/AfAZLJL4+fncaqQeDRyVffxrl4mCooS9
|
||||
DYajnw7AhFvN0XtXb5vK3HYiz9mv/OnXeoeWxYcWI6aY6LR0OwHHQQptKQSIOP87
|
||||
2mo64IbAwzuBrhxNrdrQKCnf1mtyDZig+2r6R4TP3EM3sCNAoiU=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICxTCCAa+gAwIBAgIUI2oh2cgrnM8p3D/8Ijd06wwY/UQwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICxTCCAa+gAwIBAgIUJctkeS6qP+WqsgOLbjATJuPlN40wCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMBMxETAPBgNVBAMMCGVtYWlsLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf
|
||||
vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb
|
||||
|
@ -8,10 +8,10 @@ uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S
|
|||
O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR
|
||||
3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv
|
||||
5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxcwFTATBgNVHSUEDDAKBggr
|
||||
BgEFBQcDBDALBgkqhkiG9w0BAQsDggEBAIpPVolSwoZTwhouPemDUJTP8cZ/IPTg
|
||||
0GvzU07GH7y0Q9svPEBELRdgdHTWk3s5FaLgVGYStzs9OOpNj4fiP+CUJIwKlm6L
|
||||
Kt4mPganE67SRvHHYMzH+jjaL+xNl0Wa0O9ms+k+DQ+zB57hX8qE1oMszq00jZxH
|
||||
VIRl767e66Jgh89ac5BGoj1KXJxtUIocTKC+fMgUHbQ4oZ2v1IU2CeE6k2cvWvcU
|
||||
gclagK4EgWzIL8O2HLTLkLN163yWBYiOWQTOI+hCqsLz1OeU+J8pZ/eEYemeUV7g
|
||||
opZ5aLRzvXAkNz/eaeygEAu+6wkqVj3Btcabvx7dxmLkwDV8PjJsscs=
|
||||
BgEFBQcDBDALBgkqhkiG9w0BAQsDggEBAIFmRk4ZfcxWjetAoyYp0bIFLr5AjGqv
|
||||
ecmc0khsRkW7NR23ywJsRsCU1u82JIGrE0bpDu/KQPAMJsi6QMc9hZEOzO1t1QmG
|
||||
OJFLhCNTe+wf+5X+UKHKo01lEp7vDcO7DjuZIgEZSyOp9qbV88AtEiqESIzRBWYp
|
||||
dL15cS1PDH8fa5k7MHCAh0C/HeDRD5EP8derIWWrFIesEdJAhwzMRzJrCWIqzLPP
|
||||
Lv2gsXhehXCN7U14zkoGU97sSE09k5BopHd4fgqZesSApJrd2OenQAzdRIs3+UQy
|
||||
iCs7oLH16lOl/yeRxVjcHRWaSRM47eGpn5+YOnGkoE/lqfux+jjB3rc=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC0DCCAbqgAwIBAgIUBdYRNGqgoPy8QL2qxNIAIbGiUsowCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIIC0DCCAbqgAwIBAgIUfQIwxuYCoWiJuu/qTiEf7fbljnswCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMDcxDDAKBgNVBAMMA0ZvbzEMMAoGA1UECwwDQmFyMQwwCgYDVQQKDANCYXox
|
||||
CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR
|
||||
qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv
|
||||
|
@ -8,11 +8,11 @@ WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+
|
|||
rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv
|
||||
JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5
|
||||
Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6
|
||||
clHEMdUDrNoYCjXtjQIDAQABMAsGCSqGSIb3DQEBCwOCAQEAB1QaKkpRAhxoeSa6
|
||||
vfhiJS9a3kC+ChE/0zRqu/wVaNkxlmnq6rR5e0iZ7K2Xo7FDPxfC14UolaTFs7KH
|
||||
bEA4XzCvctDD7J1MTtcGZKDjH8ua4unpm8Ux6cnXqy3SpHzirshxU/cxOm8JtjmI
|
||||
89Xq1BQ34fck+wNkK894d3+uniMyy4WrAiVeQHWQ6cUnzqt+8THgWXoRQSvMgEcM
|
||||
ItSIylwll9pILylS5p7wI1upXkZD0V72WR+Pp/XSP07MOR13MPkAjZxXP/8hGQRR
|
||||
URtLhwGrVf5Ovc9JnFhv3CqkKR/sEcGooA3VcCafVnxyucj1bmXmbkgWCE+b/zMQ
|
||||
cVSPvw==
|
||||
clHEMdUDrNoYCjXtjQIDAQABMAsGCSqGSIb3DQEBCwOCAQEAJ2fIigbkc2Lh5Z/s
|
||||
Y7s4o0D9UnzttXjjEqKYhttk6PJnmVYG3zn3MBmyWPhDcXYW9fJwx7IOcC0woVdJ
|
||||
yjkVZUIlJY6xAqIC6kVNtbI3PJ+mji8qQk/ecXCwhTGk0H2lZXrUtc6WMmD3GUIP
|
||||
yNQGN/qAniRLnXzzVY3MJPLKKSlWSJEJCY4F4uDwBtwudPc+1yRIR6XblEL3dazS
|
||||
H2kuIzGwIu6/i3AN2WIFWFhcuRTfLZINlNeH9gYEaUrwI3MS0aMPqGXtOHz+imZl
|
||||
RwNng0xaiDxZXcEPjrRw5HEZcIEGBc6X8WtSzbWufiWBqMue1ltEpc1AkvUamuB3
|
||||
KJxYPA==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,16 +1,16 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIChjCCAXCgAwIBAgIBCjALBgkqhkiG9w0BAQswDTELMAkGA1UEAwwCY2EwIhgP
|
||||
MjAxNDExMjcwMDAwMDBaGA8yMDE3MDIwNDAwMDAwMFowADCCASIwDQYJKoZIhvcN
|
||||
MjAxNTExMjgwMDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowADCCASIwDQYJKoZIhvcN
|
||||
AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX
|
||||
bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ
|
||||
OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9
|
||||
uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb
|
||||
t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO
|
||||
NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATALBgkqhkiG
|
||||
9w0BAQsDggEBAKAFuEA9TJ+o8myZ0AciYyCjsIcQhfPvL16vfhVmbr8IXudjeIQm
|
||||
orBPLWOZWT/IVeLOYU+GecS86IFWdBjKLOMoPkZC3o6nQ95txGQrODN1uMQOQBc3
|
||||
0AMQFnKbGCgoN8VtAsn7zppipvc6FcG83fh8YnrtGa8r9LBd5r2lX3npvG8qmhWD
|
||||
J+2heHQp8D3NfCzad+jQy4hUhHalbH5aTky3T/1UGfgr/cXsDAcZb09Wd5tzDVpS
|
||||
CP6iZyumHdH24ta5yYTHEEKDtR+/YU987crD79DcBK+7K2k4feFEzLfPDzmbtM3G
|
||||
ZadO9SSf9GWHUovurJJNJaIBMYpNGeq4nT4=
|
||||
9w0BAQsDggEBAF/OD4h9UNl2afVbw/Hv2dCV5uMyDV3T8iEUI9eiCvYDMAOElkAN
|
||||
NZbDfGfQdg8rNLKG6r7Vz8VBu0T/Vn2lswtKYPll63ANv9qZVtKGsDTGzN8JSC0k
|
||||
xgMbtVsj+OsJs81hmNnW6xw7wehpPw3l1UakAEb6dbYuYCanR/p/u/hvTz7phe9D
|
||||
AsJyRAo4a+QDyeqgAPKrzTatawshNnz9O4QhNzUqj53fMkpUq2ebOyIGMOvbh/N5
|
||||
nT6AVT2wn95mWawnS5v2VTRPALyMkgbl+0bb/VzXHN6CjDHO+n239lL2uQlAZFHe
|
||||
8pKr4lmb82dLU9qUFbY7exLyV1aUyYSXSNU=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICpjCCAZCgAwIBAgIUS5/RALAav3GqFmr/hG5FumIUs/gwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICpjCCAZCgAwIBAgIUCwPRyN8HCSE5XEIq7e2eEEe1OdIwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMA0xCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu
|
||||
Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO
|
||||
7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf
|
||||
qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt
|
||||
HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx
|
||||
uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMAsGCSqGSIb3DQEBCwOCAQEArANWYwZp
|
||||
g5Z9sRrvPIaEjgJO4fnTf5/3nECTFljJH7YjGzFhnEGk52aRGubowhTOxAtqK1lc
|
||||
cA5QRMuQ/Qrr7xZOdGfoxoMnQXONcEQNobcWbxa0Z8VZrpanAhXevlk5Z/8it96g
|
||||
uLtCmgz32L6J2FpsftHI38+IAGjbgZjyOnyr4jGwgltZUKV1YRGClnMQnI6N/8TH
|
||||
UrESziJ6JmVWnIwvKWvtwy68gRLvSaJ+lD1KTrqOVris0yPcR+dWlXaHovegxwDB
|
||||
gkhtFOYJePK8p7op+WAyKlM922UYBC4X2h/4QeySrC2LYauGFz3ZARO2ylCJ1CsJ
|
||||
ypuqIXstbO0h3g==
|
||||
uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMAsGCSqGSIb3DQEBCwOCAQEAt2CF0E7d
|
||||
QYnfn/kc8hb6GF6sYpCFA6egEzr6OsYMYE7jt5mKlMJdbIxw57L8jg8IZ1fjH5AQ
|
||||
KA5cchGcgjCkHoJ7jOYfMZCubCBdrsNKx2YYWcna8WIAZjwOIfNC0Ajs3IDiRDWm
|
||||
vlBrFP9Z6bGuzNrvLFAB0lU2dM2b99DqzaYNZeQP5DcP6ZjaPkSvqOWr3Lf6ZAvO
|
||||
tU70OcTelx74Hj9bI75bxVYd71Vorv5qB77zrl7GHb36f2pkludDOKeZ6XhRgy9e
|
||||
vN6DLctM0v6fJprG50xrILDhqsTydTdjhETLaIWhF9aUHzFybpFArp8TLoWbXiX1
|
||||
eAVaASutFVprhA==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICtDCCAZ6gAwIBAgIUG62RAQRi0nQBf5QEVbVQ6tS4QOwwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICtDCCAZ6gAwIBAgIUeXeYs5jw41bNt0btBeEFNbUQonAwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMBsxDDAKBgNVBAoMA0JhejELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk
|
||||
e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg
|
||||
|
@ -8,10 +8,10 @@ KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI
|
|||
YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi
|
||||
lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL
|
||||
HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZIhvcN
|
||||
AQELA4IBAQBKExQp1zdXXkl60yJsRcUNBPbprmHDlYLFtAcAY7s8+IKn+6kWUgNG
|
||||
1wrKsaoSJUxK8MO6ULSbK8Xb9djjZ5Xcy622cOe3wk3/AIwc8nhAE6d5mtCDzOGR
|
||||
MWEn+wGsCtW+eWDTlefx/+D3zBNAsb7hyW54JKDjfRADN6VtFO4ca4Ybw92G6CRf
|
||||
g452KvRl90oZ2cxXyxOP3qdMOpB5a9DkUVS39n7iWgv//f3qlo3eUlHHoeygJQOM
|
||||
qca5cnQbYKhat2edgK5OY4eHCFOWXpxRy83/zNywLki4zozwXnTWSmuBpe2jZEev
|
||||
nOCxqVD3xceDzZ3NNkFj+c7Q2IX0ykmf
|
||||
AQELA4IBAQAs60sU1VqjaVQbGBHvBNyiQn9oTugmuEx9ogwVKhnmgRK+hYw+wgBn
|
||||
H4yYZF1gF4xG7Rt+ut+EruSd4ht8vY9ZMvKrbgMrZ6HbNIZg9oIX+u0i9Bba2lh7
|
||||
p87mCePS5L7U1gPbg/fZ8jd0FvW8EusC/TX5tOeeUnawXWE4ciqPZfIVriU0iCP1
|
||||
nKzvFtawYzWwgN+QZ1ruzBi7qqrHNDAhgLu9+3g+9QyBd40XV7/EhDQ18kViaTSj
|
||||
WmaUX7jJD1FUkGBkxjqHfgGkaYnt7UXGMDTeQ8vFeja11PJJIdRT8hSu0oTMdE6M
|
||||
WCEw02+Fc+qsYH5I6vp3MOV8wyBqIqYc
|
||||
-----END CERTIFICATE-----
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICwjCCAaygAwIBAgIUI7neyiHwgLifhsVz4PP5NKkCWqIwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICwjCCAaygAwIBAgIUU/td7MxWYwvdFLfgNUraIpy3GP8wCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMCkxDDAKBgNVBAsMA0JhcjEMMAoGA1UECgwDQmF6MQswCQYDVQQGEwJVUzCC
|
||||
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9
|
||||
PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3
|
||||
|
@ -8,10 +8,10 @@ HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg
|
|||
Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7
|
||||
EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK
|
||||
lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C
|
||||
AwEAATALBgkqhkiG9w0BAQsDggEBAGKpDaMHux0AWDSH/3scV6W+6ZFtsAH/kTw2
|
||||
zPfPad1z7xECUDzNaLjJYdTiXplBFoB9lFNmM2pb/Z98FZPLCK7wD36jLtSrBjLm
|
||||
KlDKieE3aoHHe2RANz3fEod7jV/YVuZXLNQaMEMXAdXV1qfrMOuyiYgo+Crr/EMO
|
||||
ApAQvOPxOR34Z7mBPnxVwn3w85zxrpcRzbg+UFJcr1yk0yKrlawSCB1CV/itIkCJ
|
||||
sdpqub2wRy6w3nCwaCmp92bmDAOS9K4UG4tCvwKFihYLBx1MiVmUZC90nrXSynh8
|
||||
b1hdzFnKZxzoZgM7yNuqw06Xzx0eg8yqi4wLjj+uA3UdZHP7MAk=
|
||||
AwEAATALBgkqhkiG9w0BAQsDggEBAGbVHQ19S6R62HovLt9Ltir1z9KJ4QXWNAEu
|
||||
FKicntKaId+jJY42y1+iAqQHy3FpjfLfx5eVKPW8vHbyTQSL/y0jJ9bPKepYsSay
|
||||
5McWggOxMxVFazUCOntZN282WYIg3H/OFaeRarjeHlraZjwmNxrfHKzyBJ6bBqBJ
|
||||
2vtmDez/+h+f0reutgnY1v4bJ02x/5YuG39+i08uRI0Vc+lrDiqDPYMxlmzwVvJM
|
||||
xqo9TZu9gU4XFbK8c8EUsPjMMO1gKyroiBhthtEZ8a9Q4jdeD92cOZRcPrHtYyvR
|
||||
qw9VhFLJRgLJ0DVOWqCHqYXUFfYngFezem1eeNxrz2eAbaURdCs=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICvDCCAaagAwIBAgIUI3mu28hwWjSE4ii2aLFNdXKo79MwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICvDCCAaagAwIBAgIUcy9NBl2j6kWrXfJ6Na36AnwN2Q8wCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMBIxEDAOBgNVBAMMB2ludmFsaWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9
|
||||
sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5
|
||||
|
@ -8,10 +8,10 @@ TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7
|
|||
xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd
|
||||
tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l
|
||||
8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQEAwIBBjAL
|
||||
BgkqhkiG9w0BAQsDggEBACKFOLNLmPB5hFhmP3cruJydC3/5/1sKPmig+c5MMBKN
|
||||
hgKaPhU6JalCdrHK+httffvjwXkPRdqWHWM9ILcDcAuYzJqIMofiFlW6gthTvvdP
|
||||
sqkqXdxC2S00Dc55z47mKbLPkZm7/HMSOAya6oghywLuL3US6cmKrYZZbFqrecWc
|
||||
GIja9MtthFcoS84u+GmV3pRiU+sDvwo67u7R3recmAPDU75r9Yhh68H/urKoRhre
|
||||
+10QOfQ0GGM80RP2fXg6P9MXI7/MEd8QTlUOK8xWrU6Q30R5BzF6lgwUqF5VoVxb
|
||||
WMPdPIS5gFktfqNituRNdMKlIFQ6f7YjaILDcu3upe0=
|
||||
BgkqhkiG9w0BAQsDggEBAHw1PeRKbGVaiNBPlshPnuEjJ5XN+ls3Lv8CVplvuFgM
|
||||
uvOAfuXNcLcQmqU4QZm9PvIboCAe2FTFMJ+szDbCIFaBzzJ4RnuJ0FnBZDf1fKJm
|
||||
/Nj4XikPePo5DnsqSs53aNKM7Nf5dcdCCA8kfpMm50Nw6ufWrr8HAEqQbDixecv1
|
||||
6as6xc458UU8AXKZb30VfLFAm0uPz2Y/ZjROnSqrNSB5ZRx9m4MqS3/4H7fSnlFU
|
||||
yMcetH5ovGk3xJg65qWhaRlaoeExco9E5x1nUr+eK4OmP3MXlGbxxMQx1R43Ea11
|
||||
zSyaqlhGUs06uDOl4rk4b2FmkPgGV+A26gtjMYD005k=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICqjCCAZSgAwIBAgIUT89onfON5U+5LLJ7imzzschILDgwCwYJKoZIhvcNAQEE
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICqjCCAZSgAwIBAgIURZ4xXpmcV9oh3RekbTwkCGv62NowCwYJKoZIhvcNAQEE
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMBExDzANBgNVBAMMBm1kNS1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x
|
||||
nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM
|
||||
wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF
|
||||
4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20
|
||||
yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx
|
||||
j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATALBgkqhkiG9w0BAQQDggEBAB4q
|
||||
QfSzrkQOHwIeVw/W1bpAzJ5Al92wDUNQEcw7JmZZ6Oz3bH+spBhq6xTnXqhMjCYM
|
||||
srINOlc+u/W6TqE1uPWPZvX1M9VFCWR5okXoFbc+8l6er5tun6tP7oWs7TxXzy7O
|
||||
e0GimlZ3W+LqA2ICynSYaULipFAJUvmmyFxlC3yPIawncpBWwPofPpGziF0FImSW
|
||||
PMslU5PExu982go8a6hfNAYEYH8bKetlfFPJ0DHe7/crmjE3NulnHt7HVh11OkuR
|
||||
FkjVTnuOoHGG4Z4tekPP0g1P+9m3EdTuP9Nk8hTZBThmRdAWIeBaefJJmZ91gJqA
|
||||
txFeIhOo4f1whxqNDk4=
|
||||
j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATALBgkqhkiG9w0BAQQDggEBAKs7
|
||||
7/g5m901xqDth2t0tDTFWlfh/h94KLk8d8JAAa8AMdVwpMUMc2IKPk+H+f7JkBeE
|
||||
hhJ/r4ZEbQkjZuoLSkAR6aKRprE97Ddw1LJLVish39DitEXxpyDemCIl8V6E8FpW
|
||||
CWqbOZtvUScOQOlJ2uJfPwHkh93RJbzP9EY8Hd2arFYKuExi5z8Z465feZ53mdOe
|
||||
17WG9IKKIQirr4OAxD+ab1EdMuPuXKQ9qfg4fSW/LDsb97x0/ElRfHwFDxsbEiVi
|
||||
zR/gGMW9AQhc+eW2qchjYkO0v/ps7dzjDQFDJzLAd/mlb90cK1cpUz6XVn/HagvZ
|
||||
0MRczu3MnE6KRPVpW8Y=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICqzCCAZWgAwIBAgIUIYb+7rSz8q+7zTVh7KE/MZTclrAwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICqzCCAZWgAwIBAgIUD1t15yWPBLIhosAm9w9++t/F/fkwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMBIxEDAOBgNVBAMMB3Jldm9rZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9
|
||||
sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5
|
||||
TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7
|
||||
xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd
|
||||
tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l
|
||||
8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZIhvcNAQELA4IBAQBF
|
||||
h+yu2y2s3gulEXR80Hmm45+B/egT1K2fjoz8X5BcbqT5BcbPB4utokvUQq3W6uyr
|
||||
AHVmo55vpgbWp1Thz0RoHGZ5kkYlcrYy1S7sfuoowoMXv8iWu9DSyXqhqSUhYp9F
|
||||
9sov5d5lyeHLAekss1Aaybq0vh1O1tHtKHoanlfn5HEBDjbNpQozPh/kGQTuSZVY
|
||||
e9Ikh1lFNsUCzCElC+wdkATQbo5PpGEsJqk5bmz7W9l90j7+JFdH5onIFD4gSOK8
|
||||
2hsPCFDhmnma8/CvAY08hwEYmb26gnGQbVusIPr+Ui7LjUqW9b6XAdon2teXXEoa
|
||||
vCp11ICfcHvIHhoLDjkC
|
||||
8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZIhvcNAQELA4IBAQCy
|
||||
eobd3+MhGhQvhKQax5XNBqAEmogtsv6G1ZCoAx0kKU83r3Oj9ha4VfGN0syP8NQV
|
||||
nmkecZ630QXQcyCD3RRiiLqU07N3nC5djm8v+vM5RhuDADkIwddH3WNWB+8KUJEd
|
||||
3Sym1EN6xAYdQEAwWdPno73sUsFebuoL/c4gpTjD7PF+/vPzN0c3KVanlrMhayKe
|
||||
3PLq8jST2OSdLvooa8qMYsFFG2S4A+gmp9Cx30moMG2+w1GBKZdtY2tlFx5DppIU
|
||||
AoQzUl9pvT6AFDcY2RO6UvsWF9Pzr4dTjjgk8SO05jKcmj2GnBm480ZezDx5N5zm
|
||||
+XVGgonJZRAucaVuJY79
|
||||
-----END CERTIFICATE-----
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICzTCCAbegAwIBAgIUZ71J5xveWHK5SkrwbRXbsbUtrlgwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICzTCCAbegAwIBAgIUYfe94xSwDUoffRodCo1TPdV/PaswCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMBExDzANBgNVBAMMBnNzbC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x
|
||||
nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM
|
||||
|
@ -8,11 +8,11 @@ wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF
|
|||
4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20
|
||||
yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx
|
||||
j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMhMB8wHQYDVR0lBBYwFAYIKwYB
|
||||
BQUHAwEGCCsGAQUFBwMCMAsGCSqGSIb3DQEBCwOCAQEAkDks1086hp7MS0anvQw8
|
||||
XnkD8ItCFkcVk3aPdLlwODBGqDvrjIR9kCX2aJzdChiCnKPtN5pDiyfb/e+lJ4zN
|
||||
qXoSP2ksYbFtFr7Vp/eDEI9iwvFTEubYgq9Y8etInetFxEqRQPDtAYtZF7P6i1su
|
||||
FZUHlHYHsVmCCXXlhTy6BhmJCj0ANaquHHuACty55uNw2IbNYUKN7xp1qOJO2TUc
|
||||
ip4fybk+Rdm5fJOj48W7uUBpvzfnLI/ifABuVRy2koZvIewjAwwPZ8ggWyi6PHT3
|
||||
iLrLmorNMDWTWN898zO09skrcobFKrWJCuSafAeZYCYHDC7x1uVlLDM+v6N+fN14
|
||||
RA==
|
||||
BQUHAwEGCCsGAQUFBwMCMAsGCSqGSIb3DQEBCwOCAQEAprVI8tGWBHIN2SV66ZnC
|
||||
vOfWcQguUQg8QO3Al+O4X5U18hzgsmCjqt99b+oJCJD0qWBnPPBgqY52pckCgmTY
|
||||
w73TZ5w3Rnr3v+BlQ5xPTyAQoUeutm1LMxY/Ju7m1XV44tyDnq6GZbOZLVWtRLXe
|
||||
W4UEqVex4qbCw3GOvFyHmubSNUk81v4Iexe1SmIJN8glZsVmWJdaC2Xo7qhz+vvq
|
||||
HljfO+/ejiBtZOJSf9qG6HcGW/Rf15Io0e+IA6jbZWrlAzIjBcYKumZF8LjRONHZ
|
||||
vwiCwWit/IP6KvmsHAb7wj5c0U/p1TuyGdvu/ccp6nCdx8Ya7/QKfAEQTZXnloBG
|
||||
4w==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICtzCCAaGgAwIBAgIUc97erK6I1KzZpBDPfRQkFj/yzHQwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB3Vua25vd24wIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowGTEXMBUGA1UEAwwOdW5rbm93bi1pc3N1ZXIwggEiMA0GCSqGSIb3
|
||||
MIICtzCCAaGgAwIBAgIUEfR3vHTQuzModYBSMepORIL++2gwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB3Vua25vd24wIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowGTEXMBUGA1UEAwwOdW5rbm93bi1pc3N1ZXIwggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo
|
||||
V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p
|
||||
0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk
|
||||
fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh
|
||||
W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI
|
||||
TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZI
|
||||
hvcNAQELA4IBAQAzi/BVt5ZYRAbAI1sue6Qduqlk6OwVuROZS92xoo1G+bqJuMvv
|
||||
K1jiJWeZn1xGGrZcCeyTnf+Qst4Hd34PLApNHfDPdNW9C7QiTUva4GELCZsCS0+b
|
||||
hkX1W62OCS2gY64KVriAzbdKgx8nWhxlEa8zKBJEhWsX0t6PmjCxTEp1uyyJDlgg
|
||||
vG4OEvUxywbk/MDnsjs7pJ3jUZ3DVQb9t6+z5w29AL7qpzo0CZ77YEuZsV6IuAtg
|
||||
mNG1jfg7EkWBuxhHoI9UCqMquS4S9IHhuaDQ/qK8hBvjXTRsXyCKuwvIcxEns2aq
|
||||
1fIW02nd0nX6+UxASTfY+grYNE8US2XFluE3
|
||||
hvcNAQELA4IBAQB4pRQvglUpzNZ2fH0oj5bcqfcTjE3dwEzGg7WaMD2t50zKgCRp
|
||||
2sDObvEB1Nv5SHSkebxDeS9xQ6Dghf+TvuCnkapi/6q9etP51lkIOhl6okAGUwdZ
|
||||
vO3duIvXCVUWbut3ATQghKovDYuJXKMx1OYapxyLKKCsdvTQ8LNQpPcwbpVtqWKC
|
||||
jLYpa1i/vtn4Pv8xs/ceOf10z5AdydpFBgZ8JpY0CbRI73WHR5fr1yYI7tfzaAA8
|
||||
d+OBZ7nqlg81khD/Oepl/h6/IJ3L2eB+lUZx6+yWML9jRD0HX1xRje19u2vxCuQ+
|
||||
tNo6lQr9fTRG76Md1d4fdg9+F9LGqDd+yBBv
|
||||
-----END CERTIFICATE-----
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICzzCCAbmgAwIBAgIUC/H/PjmG29sIm7mYo9C4emq7th8wCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICzzCCAbmgAwIBAgIUT/T//UMr8YnbQBWj+61OMGPKRC4wCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMBcxFTATBgNVBAMMDHVudHJ1c3RlZC1jYTCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl
|
||||
qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg
|
||||
|
@ -8,11 +8,11 @@ w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx
|
|||
V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1
|
||||
MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs
|
||||
vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUw
|
||||
AwEB/zALBgNVHQ8EBAMCAQYwCwYJKoZIhvcNAQELA4IBAQB0kH+mBoFNCKtakbPa
|
||||
WoptSlYB3v0Hivr64+6RGgbE1Ns0ZcEUpid/0PYCPo+2LE7Db6LRMmygQZ67G5Wq
|
||||
SQN9Wb2WR/RqwikX+UbsbRuTElM+QMQ2AmOKBjmF7krzixq3zP9/c+CtSN4+E6Qo
|
||||
XvH6GO3HWJ/7QdS/oGgbP63O9BszCOmZRAjNcBstwiVSxKSvJHpelbHsN7Ml4k0c
|
||||
CXRkxIebfNUcHSSAgDme7f0bGgG8XJSGONebLAJgQcq59EHYD5sE2xR0rF2lmFEq
|
||||
LO5IlW7TfTEGSQyinYO09nXcwuIbyFdYKaEBtE+ol6GIQyZGcb2AqSVXiseEWVId
|
||||
B0CN
|
||||
AwEB/zALBgNVHQ8EBAMCAQYwCwYJKoZIhvcNAQELA4IBAQCiDFgskGRygaarkruu
|
||||
gTwsX59ULb7yhXyYKZLTdsUitHi8Zk4KUmsbkBHGaek30Ud9A1GyLzuP3hb1/M7M
|
||||
FdARYO8qrl414tW3hiON36R47qtw5cO6a2YZfvxU79esuoa6uxChhHLUugqNotJb
|
||||
bbGwSMszKzkGtOQ5ZTFNc8+t1kWeQfFoPMznjg5WC2oq9Pl45Rt9lFrU3SD8MkVA
|
||||
8fLAGR5TEOY2ZvjDDMKg+ceJNIaA3SPXDTVSXWNIakJU2vsdUXThTyfnoCw0sMQG
|
||||
ZwkmKbCXioYXDB/nrjoVBgJh85JSc4KX137y5m2FK+wHzkKMgf4yn6Ql2eg/yTen
|
||||
CaeK
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC5DCCAc6gAwIBAgIUZ0oJPtx/+Z/XhMrbXNEoRnqL+VYwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowJjEkMCIGA1UEAwwbRUUgd2l0aCBiYWQgc3ViamVjdEFsdE5hbWVz
|
||||
MIIC5DCCAc6gAwIBAgIUaauScBIwFX7ueYmCXknl2gMYElAwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowJjEkMCIGA1UEAwwbRUUgd2l0aCBiYWQgc3ViamVjdEFsdE5hbWVz
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2
|
||||
ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF
|
||||
h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n
|
||||
|
@ -9,10 +9,10 @@ cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv
|
|||
OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj
|
||||
tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt
|
||||
jQIDAQABox4wHDAaBgNVHREEEzARgg8qLiouZXhhbXBsZS5jb20wCwYJKoZIhvcN
|
||||
AQELA4IBAQCTfW3PqL/kgGyKiEDJMNdg+7oiwqaU6o5PP4zjE95Rl/etZgdrvcRI
|
||||
kgQTdA4OJrW9qGQcia0lk3jP4OYxyVfkMYvLTen/cT60yBl9h7r03itzgDwPBa3d
|
||||
ISdjZm1a8tPkskwjARYh+k+aqInSN5CcrjIp73ZI7AW9DuxhgTbXrFi+LDxwgk/J
|
||||
Z4CdMcglnCMRwQ/wjaXpvuJjyOb5yP38KCb9V6SGr6rAWFj4dpkdpHL6859jDaeQ
|
||||
TEae93OtgGGFVNwoqbfSTraRPu4ei4qNDG5D1Pg8WCnu5aMsnsrhdv58zgzszV2Q
|
||||
fr/jDAA3BhKkjyFN1lc8GLZaI2hIw/OJ
|
||||
AQELA4IBAQBQsZKhZe/1VkfifLqD4bni/7VY8xfXQO4DDu9HSkFmeJOhaIzfdQls
|
||||
q4LN+HVuJcJQZD1ni24UbJib+Jh8cbuzRA8l6w+PUBB6XPeF8BfYDkSbDoIYxj6h
|
||||
OclX4HInco4O4Ul+1K0u7qF9xtMYK+xaAZqiEzU638nW2n5EWV8v7y5dJsmx7rz3
|
||||
s7boQNkjgZo7R0Lw5Z8zzKYE0jVp+dRztP/f0X9uG6YW3thFIfHbewXBKP1kiIv6
|
||||
jymQMdcdnc+LhtM5/+KJcCstGA1YUaZ7pNkU7/KyB0Ch1m+b40EOSnZKelUFkmvp
|
||||
yaMC1hUND9LZjKwnGKNwuF5HR4OX/w0g
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDVjCCAkCgAwIBAgIUVVr+LToc+550ED/EYrG46cALo4gwCwYJKoZIhvcNAQEL
|
||||
MIIDVjCCAkCgAwIBAgIUHY/2g5fyvV2MONrnjGi3fWc83j0wCwYJKoZIhvcNAQEL
|
||||
MC4xLDAqBgNVBAMMI0JlZm9yZSBVTklYIEVwb2NoIFRlc3QgSW50ZXJtZWRpYXRl
|
||||
MCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAwMDBaMDgxNjA0BgNVBAMM
|
||||
MCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAwMDBaMDgxNjA0BgNVBAMM
|
||||
LVRlc3QgRW5kLWVudGl0eSB3aXRoIEJlZm9yZSBVTklYIEVwb2NoIGlzc3VlcjCC
|
||||
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9
|
||||
PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3
|
||||
|
@ -11,10 +11,10 @@ EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK
|
|||
lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C
|
||||
AwEAAaNiMGAwKgYDVR0RBCMwIYIfYmVmb3JlLWVwb2NoLWlzc3Vlci5leGFtcGxl
|
||||
LmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhv
|
||||
c3Q6ODg4OC8wCwYJKoZIhvcNAQELA4IBAQCc749RSjx6UyTbEmLD3U5UjWE0vkoe
|
||||
QhvPPxZsTdywmvhTPolLwJrxTURyHZsbqj1ABY8895IRLzBZs90BOpzLHAhjz0yE
|
||||
hJMmBwMXUJciT6Ws3hm5f7TpbbL6iHuL8b1t5E9Y94eMYnziu1xhTfRSgmFsjHI+
|
||||
LRE42COnHq5/OdBYiv4p8xh+0D/r4IdMKMVdAnd7qVyAXuMo5ejji+UGtk1TPNWL
|
||||
zjo9n9UZZmJcCPXUCHlnBAUchXsVeIXDhx2O8NxrshrG2qvpTZFEe2lg1URS6C5c
|
||||
X7X4/QMajKsfkTSjLsXUVsbXLSSM6FxWMACFpiXdpiLSSgke9XHidkKF
|
||||
c3Q6ODg4OC8wCwYJKoZIhvcNAQELA4IBAQAAYmpIy15lrWSrorG+HfjZNckhAsCG
|
||||
1BOVYRr+s1Zks4wj1aMXFSzblgNgdRuZA20TkRfJKw40cyuNLfm5DhKZUbo+0LAN
|
||||
jthu2cHFBaQn+XV6xMb2tEKTU8rBqzAYIAnmEIlLukYQBVICL9tirC1JJhqe1/S8
|
||||
U139izFYNnSqNmss2cJOuI4VM7B951v1h4mQYfcX1Sv27qWaKBK7k9fKBWWE0DCX
|
||||
YR1nB4RlI+92ncTOwbjtXR92gqR/z1wGDOPj/0VNNUn4SKo5Xif9TqXh4LhnY9fD
|
||||
HgoZSMDxftXou1MjN0cWnIP6QMyLfg2kSN0vnQpVle6KgsxpfrgLiMoU
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDQTCCAiugAwIBAgIUQfb09PMAT1SEtF4xJshkxtV9Hr0wCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowLzEtMCsGA1UEAwwkVGVzdCBJbnRlcm1lZGlhdGUgdXNlZCBhcyBF
|
||||
MIIDQTCCAiugAwIBAgIUBUmy5jtGrDso26TeIelwmtF+KFAwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowLzEtMCsGA1UEAwwkVGVzdCBJbnRlcm1lZGlhdGUgdXNlZCBhcyBF
|
||||
bmQtRW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO
|
||||
FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr
|
||||
amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka
|
||||
|
@ -11,10 +11,10 @@ aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE
|
|||
MdUDrNoYCjXtjQIDAQABo3IwcDAMBgNVHRMEBTADAQH/MDIGCCsGAQUFBwEBBCYw
|
||||
JDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzAsBgNVHREEJTAj
|
||||
giFjYS11c2VkLWFzLWVuZC1lbnRpdHkuZXhhbXBsZS5jb20wCwYJKoZIhvcNAQEL
|
||||
A4IBAQCESfPz4M7Cm9wd3OekRNB+U+FRT0Mc3Hu6NJIlW1NSCCxhHjdw/uXUd4ZT
|
||||
/vQVFgnicOoBkWNuDmq0EEy4bezcgSCEdYbQ6DBc4ce3+q1gELBQCUqP5ocUqS6a
|
||||
nA9rRYn2ycZki5OYfW3y6XfZQHKQRDjTCKxGrsytWMJdwNhXaa8dB0pPc3vgob/m
|
||||
URxozNWu3nLMfvKiZl2wBz34vbTrV1cm4J2p7Il2nq4F0FveHfDenmp8FoaFkUCy
|
||||
n5yPuOCjbRAYMYFJryO+6aRreHjrQC3B9OQT9CDr7W4smE47IHE08IfIVhsNiCEN
|
||||
aYahky99OFB4yK9kCBJ5fhEY6qCw
|
||||
A4IBAQApr3pPS4uWz6oPEhrTO73K+JTP2VRTKgtbooPhOZ6tCRz75P729RzVOEZF
|
||||
Vf87VSFTTXUdG5Q6+SDNuCdDuyyPR4q38s+8jgv3OVfsEbhPuSx73pLAzYg727Ip
|
||||
U2ROGoVysc3JrUfwPZSvQ/i4iqdb2sVwtqR5LM1nApy5+p6Ef8cwjfm9qsdrHlnx
|
||||
3VdiioEOp+8SKH5rzfZe+1jepRODlqvFEO9gFbaqjHLzL005xAcfpsZPH5JzDhqD
|
||||
g4QiIFlm+wwQ9pTBpk1ZmbgDyk4frrxughFsbR4zDDTfJCREa5RlwH34xOkx/cTu
|
||||
ee/qZzerx61VI88GvLK87eX2ZiH1
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDhTCCAm+gAwIBAgIUGydiTcNwvz22Zpgz2Dx02e4sVsEwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowGjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG
|
||||
MIIDhTCCAm+gAwIBAgIUNRvpOhsDHEYbRf6bsiAPbvKe2VAwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowGjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG
|
||||
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1
|
||||
aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we
|
||||
adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS
|
||||
|
@ -12,10 +12,10 @@ MIGQBgNVHREEgYgwgYWCCWxvY2FsaG9zdIINKi5leGFtcGxlLmNvbYIVKi5waW5u
|
|||
aW5nLmV4YW1wbGUuY29tgigqLmluY2x1ZGUtc3ViZG9tYWlucy5waW5uaW5nLmV4
|
||||
YW1wbGUuY29tgigqLmV4Y2x1ZGUtc3ViZG9tYWlucy5waW5uaW5nLmV4YW1wbGUu
|
||||
Y29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9z
|
||||
dDo4ODg4LzALBgkqhkiG9w0BAQsDggEBAKz1r0K+VORxth3U50e0l2zywRlGjIP5
|
||||
hNGkLG0aNWifnGPpw3aMVWCvIUHa6R+7xuKg3EeqnknT0D/g+vKrzTnOVsu7tt3o
|
||||
+llvXOuRAUCoa19W4kM8/750r+c2i5N6HUDYaeMg8J/o6c4J6vnusFC9SBO8MR73
|
||||
ijnpeSOc/huVucUx8Njko578rfaRcYdD1yOHVGm/d0UF2T042WgBmmyj0W0aO5Fg
|
||||
tRgMW45lx7QY1RpLqwAOV1f3LYVgtoCkhP14skkKaqNsUIZqxSV9Z7KwXm1oZt5d
|
||||
ZD0X+b3+0JefO52/8oO/fWJt182xCb2Hsz5TtbIWpQ4s9LHR+1bPTtk=
|
||||
dDo4ODg4LzALBgkqhkiG9w0BAQsDggEBAH6+Qe/y1TTCx2w6f31VWp5lcizPkS8s
|
||||
ODfbgT9pKYqqvYDeiDu3q8SLGHTTsHWWewBCu5Jd0mXPXfZ4FEHcwbVJZUZBvQVr
|
||||
1aNBCriuzhNUyfjkvfCgM4OuxgNwjbihGDE8VzfxTiz8mDN0AgACCZaUTQnybQc0
|
||||
SW+ldxspBgQJom0tkZ+TGi80L3/5P5J2+7AchxhAZzQmebDnxNYDZXCJH8w15was
|
||||
OzM5BrQzz3vuxupO7lsRzZIzAU+uQD4bjcMpz3oMdj3/0lb0HZGMdU22Ub36PvLC
|
||||
6mYbTtf0IS5TVyLnbCNeliE6zoPnQPBzAUfoOeD1Tn6HQUQUT8oTf2E=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDITCCAgugAwIBAgIUf1H5JdnGe1twEedkLyafrWOU2iEwCwYJKoZIhvcNAQEL
|
||||
MBoxGDAWBgNVBAMMD1Rlc3QgRW5kLWVudGl0eTAiGA8yMDE0MTEyNzAwMDAwMFoY
|
||||
DzIwMTcwMjA0MDAwMDAwWjAeMRwwGgYDVQQDDBNFRSBJc3N1ZWQgYnkgbm9uLUNB
|
||||
MIIDITCCAgugAwIBAgIURex/TuOH9TNqma6czhjn0gJqzqwwCwYJKoZIhvcNAQEL
|
||||
MBoxGDAWBgNVBAMMD1Rlc3QgRW5kLWVudGl0eTAiGA8yMDE1MTEyODAwMDAwMFoY
|
||||
DzIwMTgwMjA1MDAwMDAwWjAeMRwwGgYDVQQDDBNFRSBJc3N1ZWQgYnkgbm9uLUNB
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2
|
||||
ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF
|
||||
h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n
|
||||
|
@ -10,10 +10,10 @@ OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj
|
|||
tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt
|
||||
jQIDAQABo1swWTAjBgNVHREEHDAagglsb2NhbGhvc3SCDSouZXhhbXBsZS5jb20w
|
||||
MgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4
|
||||
ODgvMAsGCSqGSIb3DQEBCwOCAQEAa1/9eVx+H48q63fB6yTK5Lk4loAxWEO59a7h
|
||||
PVRJKW54ihRH0HmQaaZtmprihQBLnzQRRJhsnIQ0og6WAWqPCLKJU7TbDAyRqoz1
|
||||
LKKs+JBFOu5NNZza2u3/7hkTVqBfwFMGm/zsnJZgEcebZr6Wbmtncu7OP0agMHol
|
||||
H3+xuP45tlmo0v/st4JUUL163u4QSUGJ2OFkKZju28in7Dpugha+FB0glagAyc2t
|
||||
Pd22Nfeieket3XMB7DSlhDWgcMT62ufg/WRLot4zh7ShfJUGAnsc/u0tDwqM5zWP
|
||||
QkpxKhULe/B0GwB7+ObAT34/Lr3bAQ79cxOfBP/WT1m6R8BF9g==
|
||||
ODgvMAsGCSqGSIb3DQEBCwOCAQEAnLI+egtdtaCj/pGgINrEi98m6gvK+wANDhDS
|
||||
RhX2IztG/xuLCXIEcecjl2ifppklo6BnGqMebuLxndygkEGXiuvTvAbtd8Ac3s7O
|
||||
Cln/JW3OOBs6a3UJJeo1rpADn5F7tSXJshnVFNshZlXACnb25JIvKKIZwEhNKCmz
|
||||
whfX5xVW7RumZ5I4BYrE16YkQKQ9Fc7orioPbcTfH/zmoBBseMFi9UHCsI/u6P2/
|
||||
2DpdD2hlld/Cy0cEzb8IJFnx1CYIpfKCP2OZR+YEn8i1P6WwEyYy47YlFmZGkVmQ
|
||||
t1zEXNWT6xdW9+jREoyvl2pb/4BzQDzUhUg6P1jbFqHKtBgFqg==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC5jCCAdCgAwIBAgIUcfT2W+hqx+xtzoUeW/Rk4GxQsvkwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1YxIENlcnQwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowHzEdMBsGA1UEAwwURUUgSXNzdWVkIGJ5IFYxIENlcnQwggEiMA0G
|
||||
MIIC5jCCAdCgAwIBAgIUWdJEDrMcdJcIJoGstXeNPWoUzCcwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1YxIENlcnQwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowHzEdMBsGA1UEAwwURUUgSXNzdWVkIGJ5IFYxIENlcnQwggEiMA0G
|
||||
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk
|
||||
NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC
|
||||
fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m
|
||||
|
@ -9,10 +9,10 @@ CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM
|
|||
HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m
|
||||
1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGj
|
||||
JzAlMCMGA1UdEQQcMBqCCWxvY2FsaG9zdIINKi5leGFtcGxlLmNvbTALBgkqhkiG
|
||||
9w0BAQsDggEBAI+/pu+8iiO0FI/jjGM+Kc6z7ehGt8bCfEtQXjQcNpHRm7u0A9CN
|
||||
ngDTrEmZfUsU0ATXwLO9bj+ecXRmjlZSZXifqL2GFg2EPlMSbCWvQI/326Axx0jQ
|
||||
lzydPGCwhgva2/U69gq8ldSZu9uF+kD9ciM4jxprO3LVqVv+J4okoSJWbGtsyapf
|
||||
bjMRjE5V+EfMKx/eqGth7H4q9nFo4CE9gtVLuywJBDMZ0GVtkEtzQtONW4ImHX26
|
||||
CAwezURS9HICZwbaAurRcrG9+EK2yvURsJ+YAbnFOs43/hFKghGcQ8j/ZcB3yzPk
|
||||
BjTiNsIx2fkoqwaBvQLldKg9omq/HNvTq4E=
|
||||
9w0BAQsDggEBAFlYTwajTjFg0lvULVveYmWQWzPlRjdDi+TM/guuC13D9sDXN9vi
|
||||
y5ofPdtqlGo2owjEe8XII/3enZHJqJAk/zDcjVg7ErXoui54K5q6eZGN+6hdhiGB
|
||||
iT4TxrHAQXPfkXgLr6AQx0JkIO5G8l/PZDETLkxNMoFssQwb1x2D28LxYhqcGQJY
|
||||
A7h8M8kMNZiltGqLUBXdYdmM1IljJb/BlqULV7QbCh8jXsvdP3leIQCRK+vUONcK
|
||||
MjnLEzAYhNhRYWkjCBF/Q+qsPlL/aSbkupr6z4lXuCUIPF8TWs8q0V0uwGeOT0MZ
|
||||
aWkw8tsi1UYRR9Z5WdTe8l0dYF0G/kpD44Q=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC5TCCAc+gAwIBAgIUOfhaGfji7wWORLPtvvh3qwLG2EYwCwYJKoZIhvcNAQEL
|
||||
MAAwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIwNDAwMDAwMFowLTErMCkGA1UE
|
||||
MIIC5TCCAc+gAwIBAgIUWcXPQzwjDQvgxBhAb1cUwuJNgfswCwYJKoZIhvcNAQEL
|
||||
MAAwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowLTErMCkGA1UE
|
||||
AwwiRW5kIGVudGl0eSBzaWduZWQgYnkgZW1wdHkgbmFtZSBDQTCCASIwDQYJKoZI
|
||||
hvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs
|
||||
9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8
|
||||
|
@ -9,10 +9,10 @@ kqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJet
|
|||
lmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2r
|
||||
kQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMqMCgw
|
||||
JgYDVR0RBB8wHYIbZW1wdHlpc3N1ZXJuYW1lLmV4YW1wbGUuY29tMAsGCSqGSIb3
|
||||
DQEBCwOCAQEASD6B6KgSrGdbF/gu9B7K3l9wbqj6LpnTxdgDuySAHZNkv8yjR3uR
|
||||
Y17lj+AwHtmphWhdwbnRzRSFRbVIZWfGhsUqBYGcL9Avur1oGbEPsKlQ5lAcFZwY
|
||||
XknWccmfhI/BDd99CIq5oJtMvZ7b1v/9ySBSNCyiztU8mTuXEN4fIEXQ7NnIFgKb
|
||||
RNl/mZH5FBOQygqYN/JvyGCjOY5+hmOiDDt50th66s+kt8SBBP/oO4+lIBL5kDW4
|
||||
WwnRVLDGQBT5F7x0Xt4StI+Wh3gsCELRq30yeiXSOV1ywjDkivGzW4WoumOzj90l
|
||||
9ScI6+32LtTdUGkBnLPocSTRZo8CGLDU3A==
|
||||
DQEBCwOCAQEAqbRuhfV+zSaD8FqWMaaX3Q0V08aazNE+xt/4z0E79Ap0LWUs8h2j
|
||||
IVC61EsJKrgYMseNd6DqyzhucQYgH1yuyZjb9VC+BuEA/GvcbzxMKr9jf9hMFXvf
|
||||
PtyrAPDKbkscfjF1Xpq0nfTld0zxDaa01lZEyY175Ga8OM0oUaOr9tsa/m6d4/qT
|
||||
2J1qOus/doyoD8CJB5vOAFjK1C0u4EMmZoayjiOQori61wsmcn6I077Pdwbhi49d
|
||||
iuZGc3UU9VBPyQ6CWN5tP2e2OSfT3p1ep/7gb7RJXQXEHksokq53Rg8HM97wQxLi
|
||||
134jJOJFJmeq+8pZ9NSTwrA6mo1nLfiPwA==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICvTCCAaegAwIBAgIUPaQULYcIRJvvQrmqScjw4oE73zkwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahE
|
||||
MIICvTCCAaegAwIBAgIUQYl3Nyjq38ZPBpJZBi8APD7LGXcwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahE
|
||||
jhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1
|
||||
a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1p
|
||||
GrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW
|
||||
2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcO
|
||||
p2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJR
|
||||
xDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYw
|
||||
CwYJKoZIhvcNAQELA4IBAQC4DOrJRuOJv58C8WhWUDeArR9JcOBk0Lzarzk0xE1M
|
||||
JpkmGi0EOlxTCBscbjA7rOqLn5/Rfkqyt90AukdAwUuz6q+59D8erZAwulkMT90M
|
||||
GGQPbVl6Jqk9zAYhB2hl7Go6b6Y2YAOJdIBMbEjUJce4dY5UoaEAvDbXQLBouJZo
|
||||
Jarc5sFM4Aq0OjXVFiF22JHIAs/ljTqRFDVL7smr4XfWet2AcPMhnaTFKMpzbfa2
|
||||
C1L0SebD8DR0tnVQiGF+OqvbXrOoxFy6zuBydYPZWR4GOc/zvAGBS0XwieOKq3op
|
||||
J0G3TTIc/6NtNlHbf6NT9ien6FMdk/XvqV66YVHLFsF/
|
||||
CwYJKoZIhvcNAQELA4IBAQAbXSUfUwpYXLieOce+6P1Sqtcg0nuDf46vmR+1vykN
|
||||
sRZNnvsO32PNCh+WgsvJ/Yy6SPS3LKG/NwBK2yH0fiq/b+JPK15cvV/hRkb23ght
|
||||
4D1+CZ6hMgirvMDFMk9wb24zUMn1MshHSfed5RM01GCnSTsBUldM93bFaMNlghyH
|
||||
AIFz3aj2VTMZvL8XeoytDChfE/RYoI4eFD8O2MPyRCkJ1grN8PmpoU5xdiDIpKIp
|
||||
4UK5/SnRnyci6oBpjJTECnboTv0qyfpODr/QBU5iO+8Yg02Uco27fiy5MmcejRg1
|
||||
7+pRFfrvBU7DP3uJhGOTKZzsrgsrYK6qSo7zbPyhD8oJ
|
||||
-----END CERTIFICATE-----
|
|
@ -1,6 +1,6 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDNzCCAiGgAwIBAgIUdakyQxHEOz8eq2oddSdoUYT0DP0wCwYJKoZIhvcNAQEL
|
||||
MBExDzANBgNVBAMMBmV2cm9vdDAiGA8yMDE0MTEyNzAwMDAwMFoYDzIwMTcwMjA0
|
||||
MIIDNzCCAiGgAwIBAgIUeWc23T2mQmvsb7b3an7jH8J3eAwwCwYJKoZIhvcNAQEL
|
||||
MBExDzANBgNVBAMMBmV2cm9vdDAiGA8yMDE1MTEyODAwMDAwMFoYDzIwMTgwMjA1
|
||||
MDAwMDAwWjAfMR0wGwYDVQQDDBRldi10ZXN0LWludGVybWVkaWF0ZTCCASIwDQYJ
|
||||
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1
|
||||
SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+
|
||||
|
@ -10,11 +10,11 @@ bJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibW
|
|||
JZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaN5
|
||||
MHcwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwRwYIKwYBBQUHAQEEOzA5MDcG
|
||||
CCsGAQUFBzABhitodHRwOi8vbG9jYWxob3N0Ojg4ODgvZXYtdGVzdC1pbnRlcm1l
|
||||
ZGlhdGUvMBEGA1UdIAQKMAgwBgYEVR0gADALBgkqhkiG9w0BAQsDggEBAEnoeMK3
|
||||
VQ18/OA9LzFSlkr8YFLnz/0iL8l2LnftDtcoTckr3Zhyo6HdQDYvWf7Ox1sN3BLB
|
||||
PFgQ0bEWSLRUSCTuUjLM+gKR8Dzo5LWY3ZyHh851NRP4o/mwXujr4qlMiCpKMlJi
|
||||
itjIIPEID2/oFdf8uujH+q6/Mk038v+Bq0FcfLmpcfmsptCHza1Ryw2lxc3WVvOv
|
||||
J+5t6qA1H6xJIVcb0dQwF5doTMV27YDmuLyg2VTKnoF4Fux/glH1v/YXdfxi6WKC
|
||||
8L7jeeVMurd3huWLRIoBimOn26e/wMQJAJMOXfwnYU1RULgbwdFCVZUeSNYW4pDY
|
||||
4ga6LzbJdLBvb6k=
|
||||
ZGlhdGUvMBEGA1UdIAQKMAgwBgYEVR0gADALBgkqhkiG9w0BAQsDggEBAHZl5S4d
|
||||
aiBNutInbA5t4qjcyhimG10JI70r14ijN5RXNf0TjCJjE1GDCEz3/VGAH+TFMO+c
|
||||
6jAKGro2hojGPwnth49D359dMMgppcpRGq+G4paB8PuXcmTlF3slFfDa8KIay4bB
|
||||
+g2db724ctqtXEHE5/FcmpTNkZftO1lHCEw+O1Sle1Firulo75WivLWyNsOh2znO
|
||||
+pBQ98oYqb3q+LmKnlFw61cFLcpJ6qOs9d0X0IvGHbh7KL9Hc97orLZ5qH3UsV7k
|
||||
Ews3BJjSqjZj75nciNzQUfEAYCK+t/I/tDSgebn/Ka5bVAv0iuglYHQksc4oXVgB
|
||||
WIn/SxQDsNphGGQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDPjCCAiigAwIBAgIUD91RYDYNkAEZj914Ztj5ISzYywEwCwYJKoZIhvcNAQEL
|
||||
MB8xHTAbBgNVBAMMFGV2LXRlc3QtaW50ZXJtZWRpYXRlMCIYDzIwMTQxMTI3MDAw
|
||||
MDAwWhgPMjAxNzAyMDQwMDAwMDBaMBIxEDAOBgNVBAMMB2V2LXRlc3QwggEiMA0G
|
||||
MIIDPjCCAiigAwIBAgIUJ/RiEbbZUXgHnSnds1C7ViloXtQwCwYJKoZIhvcNAQEL
|
||||
MB8xHTAbBgNVBAMMFGV2LXRlc3QtaW50ZXJtZWRpYXRlMCIYDzIwMTUxMTI4MDAw
|
||||
MDAwWhgPMjAxODAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB2V2LXRlc3QwggEiMA0G
|
||||
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk
|
||||
NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC
|
||||
fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m
|
||||
|
@ -11,10 +11,10 @@ HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m
|
|||
fzB9MDoGCCsGAQUFBwEBBC4wLDAqBggrBgEFBQcwAYYeaHR0cDovL2xvY2FsaG9z
|
||||
dDo4ODg4L2V2LXRlc3QvMB8GA1UdIAQYMBYwFAYSKwYBBAHrSYUahRqFGgGDdAkB
|
||||
MB4GA1UdEQQXMBWCE2V2LXRlc3QuZXhhbXBsZS5jb20wCwYJKoZIhvcNAQELA4IB
|
||||
AQCGr7tHhNrdziIH9DlTc6KOtwgHAC/9oq2t5r+nTw2PAzGnXlVDhechXaXHYJJ0
|
||||
6PAEh+VkN+QGluG2qUfQsKDoMMNTOdJekZWlnhPuAwQPfjzLa06yLbmzMwUSHJZU
|
||||
XdeAbf1o79xyMHfJMcmA5pduAv0RAsAZl6SyiR5Fm6nORHVHWu0Zw9WqPDBCb+BW
|
||||
Mx2Lgl3M95jAbUeR2HfDOHTh3Crpf0V8FL2n9jFgpQ+niO3JFZOBg3dVQ+BMIov/
|
||||
pldY1jGnSAaf1xGh3vL5ildKQVH2an69KjIliwofEW0qq6q4OTZgZXYBuARzGvPl
|
||||
Pbf+6Wnb09vLKtJ4QXy9cBHO
|
||||
AQBvoPaWE/YaF3sD+tYoAGdjNDbmQcP8QRhVG8wlIWSAfk9RRbvUbs8RNjdXntYV
|
||||
8J4ikq9/ajwHN85rJsRq3054qbqjit2Cn73tVhTzhe/h8xnXjLA357w/jXXXx1lD
|
||||
VZKxUvWqTvC9tHPjF3w17A2a1/3OltdLHPfzWF0Zf6Zo4uaaI8x+ayMMF6MCS3ZC
|
||||
FM2fNvIW/euVhjtLC3b+++5lMq/ZZCuJGB1kANDsX5LpXSZ23AXNhPrPxvgkmfoB
|
||||
TPoBoy2kD814qljp8G8RguNYpaz5wSYXZNROnVBCqafEbE8VlIAwAxWp5H5qN6Et
|
||||
F3OoQMb5dBIffK3lNw6UjFaZ
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDPDCCAiagAwIBAgIURyUvvAxBjllsvSknUWv3jipp9/cwCwYJKoZIhvcNAQEL
|
||||
MCQxIjAgBgNVBAMMGUV4cGlyZWQgVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxNDEx
|
||||
MjcwMDAwMDBaGA8yMDE3MDIwNDAwMDAwMFowLjEsMCoGA1UEAwwjVGVzdCBFbmQt
|
||||
MIIDPDCCAiagAwIBAgIUS9fUW0vPRYOaV8nstqC62Y6Qk08wCwYJKoZIhvcNAQEL
|
||||
MCQxIjAgBgNVBAMMGUV4cGlyZWQgVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxNTEx
|
||||
MjgwMDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowLjEsMCoGA1UEAwwjVGVzdCBFbmQt
|
||||
ZW50aXR5IHdpdGggZXhwaXJlZCBpc3N1ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
||||
DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg
|
||||
2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ
|
||||
|
@ -11,10 +11,10 @@ DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W
|
|||
iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjXDBaMCQGA1UdEQQdMBuC
|
||||
GWV4cGlyZWRpc3N1ZXIuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsG
|
||||
AQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMAsGCSqGSIb3DQEBCwOCAQEA
|
||||
Qv41tO8/5rlJl6VWYHkC27tK5XCf/0mvn5j6na7d4bo80yf8wIctL57smoIO5vIv
|
||||
qPt6BfnV2wfSqdWq5yy8/INuvwi6lgOQg7QLnXXSq+qLo1PcKjpm8ibHlfY3N2Iv
|
||||
x/+SXoznLVGitklawK9Wp56y0iyCYNUyH/eLvWh8Y/1E6UQw/Co7DA//3wdv3he5
|
||||
X3hr3EnKetvA1KWCIvHAz52LLBI3ypR3ffPtP4pFDH1gPn2jNDEi9ov+u+lWIb7T
|
||||
xl2xqokM6+IA6zLRHVl0o4CyZUXIhXcrUeyYbPj8fA1XLsF3kIhfmiNTAR2hDT5O
|
||||
bNF1z1x1SK41crHd1Swphw==
|
||||
alq65e2NhGZhr/ph19pR7V6Tijqwd5ZubfMOQX/kVex5EerZGYWvc31+wBk6nf5r
|
||||
0z6MscHAtu/M6kN/obrFoYYro7cWFCBd6GeaSG6aDBqrjT2nnBuZ2TGICRc4h8jM
|
||||
274y1x9qzC3/kzXKS0XqeFQmbwJ9eEaqn3m9Kb8jQPbyC+hZyUFatGhcKYbFPaAo
|
||||
fdgZL2FQpJ9uG1QsblYQ1ERBvbabN4Y0jg5XFza5nQftFkY6xevmYt7asc+npNkv
|
||||
qh2aNL3pmG9E0hXZD5N3LMbndP8rzG6vnBq/6SO2eGtos2AjEVXGypJzFhBGNOfs
|
||||
mwNzXXuiatkIHp2r5pyQuw==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC+TCCAeOgAwIBAgIUW38GKpYKu6VNBPy5o4Sfa4L8WgkwCwYJKoZIhvcNAQEL
|
||||
MBkxFzAVBgNVBAMMDlVua25vd24gSXNzdWVyMCIYDzIwMTQxMTI3MDAwMDAwWhgP
|
||||
MjAxNzAyMDQwMDAwMDBaMBoxGDAWBgNVBAMMD0lETiBDZXJ0aWZpY2F0ZTCCASIw
|
||||
MIIC+TCCAeOgAwIBAgIUPxkDf9AiLxVWjs21J/3by0oWUJcwCwYJKoZIhvcNAQEL
|
||||
MBkxFzAVBgNVBAMMDlVua25vd24gSXNzdWVyMCIYDzIwMTUxMTI4MDAwMDAwWhgP
|
||||
MjAxODAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD0lETiBDZXJ0aWZpY2F0ZTCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ
|
||||
6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk
|
||||
nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N
|
||||
|
@ -9,10 +9,10 @@ nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N
|
|||
JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd
|
||||
7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA
|
||||
AaM4MDYwNAYDVR0RBC0wK4IpYnVnNDEzOTA5LnhuLS1oeGFqYmhlZzJhejNhbC54
|
||||
bi0tanhhbHBkbHAwCwYJKoZIhvcNAQELA4IBAQC3QdFZLlqhdyBz78Y+89dkdSpb
|
||||
Xn2V+FLXNbPiAn91HVCU8+9rVINyjlYPhcKqCF/YLOg4+aabnbkJzaYk24BO+WR2
|
||||
x4TUaJ1R+WB3zrG1IwyleTkvkCFml7nXZkulRIgxFZG1O3hbovo+BWsQHUNOvsbi
|
||||
wdk2IMAaCSSX5l7bFjBY0mMP8dMm21pcnCjEx5NnVqKrjmAI0xRZu4uYc8TKwthY
|
||||
ozcLjk/LtAalLu4xUpPhoEJtrdcu3TDOuItK0X0GhAAgJ3F+uD9ePxdRcyjgePWI
|
||||
J2mcGIeYW3ktZXqEjOwcyoFQfu8Yvnk3itroMRi5e5rgZzojtM+SJ4AqXZ63
|
||||
bi0tanhhbHBkbHAwCwYJKoZIhvcNAQELA4IBAQBOBtdU6gEu6bu2pVN4QobNL1eS
|
||||
TFEGDazNKDq2s/90ddUz7DL029rhnzaIJib7dc4/dxgl5TgcL/8PwPUHRZXteRTX
|
||||
3hAA+XCunBacQYfZDiG8Bpp1ClslU0FVOngivFHw/mseM7hxOCAJg++1oa1uCqBz
|
||||
bcVvau/ISa/fApWBICmfRjaD7ztrdVyE5b2M90T7ywedBJHShk8gpJKp3s2/neQB
|
||||
CcBp3LNoIb0JDMZCk4pVCNTRB9DOpa5zMTu/Emd3EpV9wISEGvDmNUGmuunrgr2h
|
||||
xZ01TDSLknEJyZR7IbMjkhS4SFpIc6bK19h9yblzDUcCJj+ZH1Po23Fk6muT
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICszCCAZ2gAwIBAgIUe8UEyCNIXKLw+0D5a/t/+y4IClYwCwYJKoZIhvcNAQEL
|
||||
MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRlMCIYDzIwMTQxMTI3MDAwMDAw
|
||||
WhgPMjAxNzAyMDQwMDAwMDBaMCkxJzAlBgNVBAMMHkluYWRlcXVhdGUgS2V5IFNp
|
||||
MIICszCCAZ2gAwIBAgIULXNWBRUzJ/V70VPd4+9U6rf/lYswCwYJKoZIhvcNAQEL
|
||||
MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRlMCIYDzIwMTUxMTI4MDAwMDAw
|
||||
WhgPMjAxODAyMDUwMDAwMDBaMCkxJzAlBgNVBAMMHkluYWRlcXVhdGUgS2V5IFNp
|
||||
emUgRW5kLUVudGl0eTCBnjANBgkqhkiG9w0BAQEFAAOBjAAwgYgCgYAA0puxL7hP
|
||||
3c0ps6UZy2bEO42Pi+VFunk4TOZj7QPfdZkWAOuSB5DSUwzs5UTbmacfBYlqPtIH
|
||||
FlU0qpkFfkfEfjvIGtpvoeEuNyaLUEalUmj52tfMtIXYGi4Z1Q1PC2hUrK9te+ad
|
||||
mggxNuFa+o9TwcjIT8YHcnndDlXXNppb3QIDAQABo2UwYzAtBgNVHREEJjAkgiJp
|
||||
bmFkZXF1YXRlLWtleS1zaXplLWVlLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYw
|
||||
JDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzALBgkqhkiG9w0B
|
||||
AQsDggEBAJsdUB8a2j+CxH9RV6uC8AtnXemuAcq0VTo+VucF2A77GNnwO7QetwGk
|
||||
tAqpSvepDG8rOjBHtrXntZ9zLzuEOnm6DDpyG0DVI5hkHYXfsEtSTRRis9Sp0uFO
|
||||
9eE1JNdZjX+JdviKHmM35C2KVmLSwntyx9jMesmWJ3OaA5mxDXD7kpUPJumqMRFb
|
||||
ZyIsvirrEkJz5VHOeJxZ4Q4ZGQicYzuvoHzewcOqLK2l33/YenfSVfJIdtuWTq68
|
||||
F/5n8dFfqpdhk+uRtSOWRUTCZe552YHzeTkINw/AGx6Is9Gt00LTZ5/F1U0SvTPS
|
||||
m8bzob8vj7GKrm5Gxl4dF0gy9aMUqK8=
|
||||
AQsDggEBALhNoeoHzQoeaGR/5bxF8VGE2XrCPoDatHwanND8rp1esVsmkkOSLof1
|
||||
DXgjZpg9ZJWw1PnprkYkV3XU1PIZWfUh/B/ir7QnsjRrORfJ+BP3Az+Sf1vX8fTB
|
||||
rfInVWtmRzTkzX/taouPBwJj+CN14hncbaT1FxX74XXmkZXHf2MfRjHjzuB1dNPP
|
||||
dAu+YVJSxZMv7QD/6qYZoy81dfqcN31IjxoFO0039ZmKrLpUjOZzOnmqzy0+wJpc
|
||||
Gz7lBvoHNv8SjVeUslb9IpP0uAqkpVYNZhWpPFpJ7xOdVKSWAUG1jDeMAD1tXC7R
|
||||
N0iiOloMHZ70o84Z6b7IB10IpoymVt4=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDPTCCAiegAwIBAgIUW1cxWpuNaqkzF0ijJHiUQVtUUm8wCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowLzEtMCsGA1UEAwwkSW5hZGVxdWF0ZSBLZXkgVXNhZ2UgVGVzdCBF
|
||||
MIIDPTCCAiegAwIBAgIUOTTgOhTYLxvzfXf1OSZs5pCrnTUwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowLzEtMCsGA1UEAwwkSW5hZGVxdWF0ZSBLZXkgVXNhZ2UgVGVzdCBF
|
||||
bmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO
|
||||
FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr
|
||||
amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka
|
||||
|
@ -11,10 +11,10 @@ aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE
|
|||
MdUDrNoYCjXtjQIDAQABo24wbDALBgNVHQ8EBAMCAQIwKQYDVR0RBCIwIIIeaW5h
|
||||
ZGVxdWF0ZWtleXVzYWdlLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggr
|
||||
BgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzALBgkqhkiG9w0BAQsDggEB
|
||||
AI81ax7NxutctzY+Bc7MIHyhNJmxhnsezibHqba0QRAJNLa+ICXundkgp8u2EadR
|
||||
LhqnJ3hd2f1eiriupbB+v/K5pnLE9GIp8Tfu/FxczptyRRQfesIabrHp0QpfRUHn
|
||||
lbDwKjik59d1YI8eSubzkdRk2W6qwnpdFNAAeXz1W+a61rfR6YaATlqpJVVcWktj
|
||||
U/wvA33UMsPKUdM5gmvfG4o0aNZj7L0MrDP/3gLKBX+YleGNHjLSNC5hpIomWuoR
|
||||
oEN87eTCmhdW5oCnIiJlycvepcwb8AjGbMO1IU/hOagKw9qXldun3/y28895ryBH
|
||||
gjObopyDLQt88mmsCNZ3ClE=
|
||||
ABOkyemfFGxIC9qMI5B7cYQJ7Mrc8qG1wlnc5aKFZ65wnBURgQUw2TtVwBOweLGz
|
||||
82qR+MnDho8inUTyilydw7WwyLAi2A2jlqcgCaBcyRh8g7/BBJ9dEP2u1BNp2r9R
|
||||
8VvTlUKj/4Ta8/GG2mEKqyhd8bpevZaaTyjQUGcFYr76/XZ0D6TxtOM0SBLrybNg
|
||||
A/hbKste6MIXE0rJwUzN2+xWBvfeFqMwzRYZ3F/393qT3vWMgHZt4ZBo/RqQzEM4
|
||||
I8k6n3s7zssdPOXHy0lezYwkCtnya2OPdGEAyABviARZjIl9Hn+0nsymZmFUkV9A
|
||||
vUw83907j7buWerBFwnAxuo=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICzDCCAbagAwIBAgIUEYlr2gmxn6hNgEBJC92l945pReAwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowFDESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjANBgkqhkiG9w0BAQEF
|
||||
MIICzDCCAbagAwIBAgIUaWHoyJhhB4GixK3MP8mpJLbOZYMwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowFDESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB
|
||||
xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT
|
||||
qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5
|
||||
kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS
|
||||
wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk
|
||||
BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxgwFjAUBgNVHREE
|
||||
DTALggkxMjcuMC4wLjEwCwYJKoZIhvcNAQELA4IBAQBRIJ5kDC83ZLwN4GMErwn5
|
||||
J/qySBFkKFQUHZQeDMcs0o/L1JYOFWxGoEjXCSoltaNp9h/g4kOKsKvjIy4o4QPO
|
||||
Gri9UnylAuH0fyd1oV6c73067QuNWdn0NHsNP4mJcwdyB5kjYcXG3yKHZrp8PdYV
|
||||
yFRrE/otq53kli6TYMvLzTptFiqsAN2juA/5e8uZeeo95+YCIGmHYnM2+KgxyY9u
|
||||
i0hjfO4rbAA/fbZSSziU7ZgEjeK3gdaMVRyFiMEVr4gGsar3IFTC6ZBeE93fMWna
|
||||
/H7WFWxmvUQbT9CDjexFnpO/zpJT8hSJWgcbRD/g6g/vp5EgDTt4//+ylEHqgVZd
|
||||
DTALggkxMjcuMC4wLjEwCwYJKoZIhvcNAQELA4IBAQCFFyBe938Z1/1WFILrNZ//
|
||||
3YlpJW0ww46JXCD+RheG2IdI2zdnbNOr7hUnLt4KprntLwmzWFYJInj+sq886c6x
|
||||
yKImpnVvjB0yDxJki85lNX6ARRHQrTNNf3wczSHdUmGlpzFUUuDkjYZS5Y6P//ms
|
||||
wPBxppkYguZVvU1s6nvHnuG2wDPKogeD5wmBSfJf8oVo03M6TqNYRK5socyeQ740
|
||||
LxXjlLYqQaUI+FEQLrCfv4LLrWpoH6mKg3hyKWoG6bEcCyvMBBJ+vDxCCpGE7b2L
|
||||
tMLn8BML+23CQ5SO53FR7dnWOuxSjnR+GRoFxw5E0qOZEGt+Fb9An5+R4xxRENfB
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDKDCCAhKgAwIBAgIUMUp2S90k4LK/8cGaRqhtJl8b7wMwCwYJKoZIhvcNAQEE
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowLTErMCkGA1UEAwwiVGVzdCBFbmQtZW50aXR5IHdpdGggTUQ1IHNp
|
||||
MIIDKDCCAhKgAwIBAgIUCcBjO7AcpbQJxZbg9Jic6+Wjd88wCwYJKoZIhvcNAQEE
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowLTErMCkGA1UEAwwiVGVzdCBFbmQtZW50aXR5IHdpdGggTUQ1IHNp
|
||||
Z25hdHVyZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW
|
||||
Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk
|
||||
cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT
|
||||
|
@ -10,10 +10,10 @@ ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh
|
|||
s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV
|
||||
A6zaGAo17Y0CAwEAAaNbMFkwIwYDVR0RBBwwGoIYbWQ1c2lnbmF0dXJlLmV4YW1w
|
||||
bGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2Fs
|
||||
aG9zdDo4ODg4LzALBgkqhkiG9w0BAQQDggEBALgpQuPyoS9htbABALX3PhEdmwjO
|
||||
1+UobPxfm2344BdkRJqMVGKHb7ipoqEcbZr5VzQUK8UhPGn3HrnTeKMVDer0tOXm
|
||||
MWpManIwvr+3GPtouZn0Qd9NVSJqXIfPc6/z+qd+X4vzP4WwQP5RaaTEwc1IegqB
|
||||
9BwahkgL9fmq9+b2GSvF4tm9kEULS+RMIeUFvtUmmF+ktIHcJfadLQHTx1GHwOu9
|
||||
lMxSrQmxG1x22Hq+BPE1512brLQg/QCRSuX5n83iuFpYPij3pMS5XaowwZrEUPYV
|
||||
+r7VUtkSiIJwYuEISoud5O6U4ZyzeasJD0AqWZEw7K0tvr7aUwR3lCC57JA=
|
||||
aG9zdDo4ODg4LzALBgkqhkiG9w0BAQQDggEBAGEUSKisSADWzD5jGCfvXOoUsYdh
|
||||
AuGaJqbQFQ+D3hJlmuPXcqOFV8oZNAaaMt0tcyH6Ak4KjpLcitRLQE2W6ChF2nQK
|
||||
qxz0OWYuFhtDg6c7JBXIT0c0/nM1NCoyDxZLK7oTpjAR5Ji6LIwuvj6uW0CLFZz2
|
||||
CqwlS+7RirFyzHr279ylFJxoGmApJjIG4Fds0BJoAdU8V4ZbDNE8LwcrYfI+h817
|
||||
y0IGGkrfpZ2eT94Ih+UfuYhKWyJ5pkxNtoG85It63MN+8i2flxSazuEk9sqRJznF
|
||||
OTYfaktXXlgBTlvr9m7P8kg+JQbwf915GMN3cgHuN00NiRqsvOQxJQl1BHs=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDLTCCAhegAwIBAgIUR8E5+ceWtBTvOha5AetRGpcomJIwCwYJKoZIhvcNAQEL
|
||||
MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8y
|
||||
MDE3MDIwNDAwMDAwMFowLTErMCkGA1UEAwwiTWlzbWF0Y2gtVW50cnVzdGVkIFRl
|
||||
MIIDLTCCAhegAwIBAgIUBUkHM4qYlHhlajaquYXsh/XJw+swCwYJKoZIhvcNAQEL
|
||||
MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8y
|
||||
MDE4MDIwNTAwMDAwMFowLTErMCkGA1UEAwwiTWlzbWF0Y2gtVW50cnVzdGVkIFRl
|
||||
c3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI
|
||||
UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi
|
||||
r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x
|
||||
|
@ -10,11 +10,11 @@ fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD
|
|||
uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj
|
||||
+nJRxDHVA6zaGAo17Y0CAwEAAaNaMFgwIgYDVR0RBBswGYIXZG9lc250bWF0Y2gu
|
||||
ZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8v
|
||||
bG9jYWxob3N0Ojg4ODgvMAsGCSqGSIb3DQEBCwOCAQEAD8yy7Gd39NUsrRKcCytX
|
||||
MTcqCEEmQNtK571afsJP1odGP6Y4CGG4p+KaECLDWask+bciiBslcE/egIJKIIde
|
||||
DtbXb4+nekmIs2Ocyf+DvucUCigpepHrRwIqxXCpk8YsoK6F5KQFj+X0wJ1bRq7P
|
||||
rzAKKxAwEgxMS4s6UpRrif0bPIaK8l3nmOjWJDplCYwDttb3Stbo4WIu+bB/BV0m
|
||||
aTc5liyZ8JzXsriYJpqY2qyfmPaT6PFPiaFahSTzUdwzxzIFdQMF4sKEPnsn/wfD
|
||||
hwVYSMqSLyBbZjHsRZkgEgOJ2EE3viian13/HfPE/PW8uB4iD1mJ5ciOGQjyxQh1
|
||||
5g==
|
||||
bG9jYWxob3N0Ojg4ODgvMAsGCSqGSIb3DQEBCwOCAQEAstqHR4upkLa4tJcDD4vH
|
||||
cUAJrMT+FzazHXIe4ukUiWG1HtyCjUiFI+NhS7YhCY2+rigO58UKgNkaG6BkrlJM
|
||||
I81gnyfljMUmukNDmOmsOtXHhP8MXdEa6ye266M/CflTI1oAnLir/6ZJm8AwcLVW
|
||||
vh4rhEjARMMPpmUC7vpf2aK4qTAcxuymei9Q7uy2tjJT4PExwa4aMBc195yXAyat
|
||||
oMnVQWZqcQE1Gq/AUzQpHsZAvZOPzEQVLk1gAnZrDLZCQucEbd0P2cJ929cK5Zz0
|
||||
8t13hDTRa4NpHeaqCTz1l8tVf70FyeQn/tpRQT3uw6aUTbVpELONOFsgt/n/7RBb
|
||||
Tg==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDPDCCAiagAwIBAgIUeRngcvJif4TaGc8e1QW61ahzoV4wCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowIzEhMB8GA1UEAwwYTWlzbWF0Y2ggVGVzdCBFbmQtZW50aXR5MIIB
|
||||
MIIDPDCCAiagAwIBAgIUexDM8FvRSX/MKvVCro1JmGq023EwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowIzEhMB8GA1UEAwwYTWlzbWF0Y2ggVGVzdCBFbmQtZW50aXR5MIIB
|
||||
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08
|
||||
E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc
|
||||
1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP
|
||||
|
@ -11,10 +11,10 @@ YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID
|
|||
AQABo3kwdzBBBgNVHREEOjA4ghdkb2VzbnRtYXRjaC5leGFtcGxlLmNvbYIdKi5h
|
||||
bHNvZG9lc250bWF0Y2guZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsG
|
||||
AQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMAsGCSqGSIb3DQEBCwOCAQEA
|
||||
hgdZQpsh0aFrFgxiPll/JdJO31zf1M7a6oD9S6Q4XYJqOL6NjL3MLmsVyYQR2kcb
|
||||
mH2+mhLEDF4t8ZOG6jvztf7I/BZHzb2YUHyc/VmG7Wfu5/nnkg+xxIhS7kuFqo2N
|
||||
aRWI3cTns9umI4mPX44lG2HGwPDiQa8hlSC6PAIL62YEZDQeT147gw1m5gtCX+G7
|
||||
J6ouQySGT+xbm/5EXWUeTUWuT5K6hYGXM1KF+hud+SdYsUSy3zrsp/dCm738gV8I
|
||||
fUFlQRjPpdJdZUT50iYLGmkdKzOuiffIt3wckpbD8cvfAji0ydzMumFrXst1YWhj
|
||||
R8C+YTNJrYm+xjtlFdlhjQ==
|
||||
CGnfn+l13zgSEIzCmZL2JLUHCKH7OilQ0tE7QjGTXo12KXUML8uNhoxXgH/z7ZnG
|
||||
0N2ya+Y1pGOyAFsj37nAipH5xsM2mP1aAlPEjgrmoskyhiMszKxr8OD8TFHOfvkS
|
||||
BlRjnGVjWpwkc2sAbHneN/aitkWDoQ2nacipdQl0OuW4jEjNXa1GE60kCmlfI72b
|
||||
aP0yN0NPnIcx8Q4M++tfQ7imJbnonxIdQGJdjHHjIRE2CNFyt2Qeb66IyK/pnEDm
|
||||
oVjx5VZPLUr0g1Ubg6W65LbIuNzalpzPBP30CAEqLXNNZ6wqKTgEHB5UB8sQnFTS
|
||||
2AZeBlTZ42e5UpU/+h8Mog==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICwDCCAaqgAwIBAgIUA82UAymwFPTOmryByanzY+FQDtgwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowIjEgMB4GA1UEAwwXZG9lc250bWF0Y2guZXhhbXBsZS5jb20wggEi
|
||||
MIICwDCCAaqgAwIBAgIUJzlO5E47g+NUJjL7EcrQMDmXq04wCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowIjEgMB4GA1UEAwwXZG9lc250bWF0Y2guZXhhbXBsZS5jb20wggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT
|
||||
2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV
|
||||
JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8N
|
||||
jf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCA
|
||||
BiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh
|
||||
He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMB
|
||||
AAEwCwYJKoZIhvcNAQELA4IBAQCUS4rF/oNhpL/qSCurIe+0EfDeJ2Q2uNUt1c44
|
||||
byMsoafu0qgtCRSlkVSYQIrslOd/w1eRTMDWGZI2U1qwDlJR6/UZ0FHBYXJMhL1D
|
||||
aWuFNYX3AxxkCsyG+TocWz8bSxufHpLkFPpq3RfxdfEqB/X6QLyT3n3IsimOOVNq
|
||||
TN0Y2RVJJ0N9C6VyfQKsjJSy2/IVT/vge1qdwdBfnJj8NFrpZpWNWZtbEsmoVr7q
|
||||
5naatxt8xTfOqQQ5hcd6K59mynKJiA/UJ/K7eCdO7kikZDfwHYm67mS2sAk6I0KV
|
||||
XRNQ3L+WyawXG1HpM50WnCXVWW78wAEKJKJ4M4K5efE+cZ2+
|
||||
AAEwCwYJKoZIhvcNAQELA4IBAQBy/KCwjrh0emnzBnuw+yEZElSD23wKKhAjUISO
|
||||
27ndrI6Gmv/wKHdgUP2yBPZbTcUT7RrzamdkOrsVASL2vAFAI1r/wHp/PXEnuNY5
|
||||
mUWVZLH3kCzJjvZXvGbdQUJhNraNbvDgV+GI/AAo+67QnSmYM0bqhaMsgbGHILGl
|
||||
qZNOE6GZdWDFBSdNIdKz3AXeKiTXduR7rb03CiuGkG+RmByPEARiUdt2xdZMxx+Q
|
||||
nhOTnBEu3KsyvJ0Y79Z6T8s3qo2dUsjHF9Kn77CKNYQFTbyoDMsBnulZZuL3uL0A
|
||||
Fn7CB+VWzVooOhq+BvbeynWGDj3rHsMQUPyP8DMKuwJZwSxa
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC/zCCAemgAwIBAgIUNaZZRRs6yrYRpiFJJCili/6JGIEwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowKTEnMCUGA1UEAwweRW5kLWVudGl0eSB3aXRoIG5vIHZhbGlkIG5h
|
||||
MIIC/zCCAemgAwIBAgIUD8+FcBmecy2K1vllEQ2SgGucJCQwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowKTEnMCUGA1UEAwweRW5kLWVudGl0eSB3aXRoIG5vIHZhbGlkIG5h
|
||||
bWVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62
|
||||
iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql
|
||||
WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosq
|
||||
|
@ -9,11 +9,11 @@ Qe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+
|
|||
ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8i
|
||||
b2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoY
|
||||
CjXtjQIDAQABozYwNDAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6
|
||||
Ly9sb2NhbGhvc3Q6ODg4OC8wCwYJKoZIhvcNAQELA4IBAQB9abq4vsm5Nwt4xUuA
|
||||
Og9gRQKjUOGNLg7DuGh1B1rgP/qXt6+Er6CRPSI7N2+jrldDnZ4HCvaCjFa+Gpu9
|
||||
dyC0IF27tWpczl+uGwdoo80VM2eJxFx40C8pzDBZsAHU9F9mx1vBvXuwO+tX9zGc
|
||||
Ngf14neY+3gZcQWsDkzbxWrM2ZyGjjvIL5Zaqd9KbBhxKvTXB1MpAsP49cq+Gdbx
|
||||
uXMP2NFRUhUN+M3JZO+/8iYkHJ5b+A523NZIZTa696QkLfDkIMZvUO4Ly80K+aOS
|
||||
liT5CPMf1MNeBMAC0WlK0DX2RGqOh0gePwxLhc1ce2EtydBR8oGsgh3pNf3/SXcM
|
||||
G7Wb
|
||||
Ly9sb2NhbGhvc3Q6ODg4OC8wCwYJKoZIhvcNAQELA4IBAQBiwTfHRmir5VnSNxOs
|
||||
S806Ao1xXqaz7ff/qi32Nnio855qHulmKjsRfmEv09N7/PNFkAa6yILe0/8YdroC
|
||||
aOd1iOdawsNMoeud7mD0FjuOYcjSnCx0WTeW5LZ/yXkgKwA8+shZzhr9TYiXQtnt
|
||||
TIgQma15CyjpFp9ztHj6MtInVFhjDxe9DzJsgLv8EAxbLacPN6ZFB6DevvI+NL6M
|
||||
wsy27OMdFvW7M4AWlWIyCFJg1moxaw8Ht8vUooe3EWbRknuM5IasgwZDt5YUeXkO
|
||||
0nQF4IKtLoASla3UOL7exkMLJA7kE4zTlOKADXi56lNZd/2ck/+wd9hrwo8aXLsO
|
||||
T34M
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDTDCCAjagAwIBAgIUO5jc5+Ptwn4v3jUNYRL7xdZ90fgwCwYJKoZIhvcNAQEL
|
||||
MIIDTDCCAjagAwIBAgIUd2Xdl3VR8l0IU2OPSgy6zPCjvaQwCwYJKoZIhvcNAQEL
|
||||
MCoxKDAmBgNVBAMMH05vdCBZZXQgVmFsaWQgVGVzdCBJbnRlcm1lZGlhdGUwIhgP
|
||||
MjAxNDExMjcwMDAwMDBaGA8yMDE3MDIwNDAwMDAwMFowNDEyMDAGA1UEAwwpVGVz
|
||||
MjAxNTExMjgwMDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowNDEyMDAGA1UEAwwpVGVz
|
||||
dCBFbmQtZW50aXR5IHdpdGggbm90IHlldCB2YWxpZCBpc3N1ZXIwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0
|
||||
7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D
|
||||
|
@ -11,10 +11,10 @@ rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd
|
|||
q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjYDBe
|
||||
MCgGA1UdEQQhMB+CHW5vdHlldHZhbGlkaXNzdWVyLmV4YW1wbGUuY29tMDIGCCsG
|
||||
AQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzAL
|
||||
BgkqhkiG9w0BAQsDggEBADVrWCQKRidNa6fzpdcpQOry5zvOSLWIcRUZKYzwzKe7
|
||||
hkF3CsaWUurlesR6Qg7cM2q2mXOQv7BvaG7luYN1jCGJwPliOUKn8sJqH56qkMls
|
||||
rzYYKMJhK1LUKpgg973Gxy12Zwg9zaGhev/OTnLemQSu2xQw10kUI3smkBL1YxlA
|
||||
blRDy5z6aWwM2ZXzzdQzjeYV0LZHMF/z3xpfoKNxZuApF9OldFnEBk+27m8NHb7S
|
||||
ZEArrdqMfJDi9MqCihCuBRGjphKS9iQX3KIYgqrDMzIf19EQNRQSLgWLHn+JSRNg
|
||||
TzrZS+kIWJQypSv45ejSCp8rYx9OVnj/U9RJ908R/RM=
|
||||
BgkqhkiG9w0BAQsDggEBAEI5yQNpc3afAa4iN9uVBBDv9gT3X2FbhrWKCNYbLsRD
|
||||
dtntFIuZMHJvH0IuKqgUoDnFMJciOkhY8GrJUi6bZIOd15YL/jsodJHxYO9g0vT0
|
||||
0E33/Ka+0DEy4g/skJTy7xQsF0OTw042Aoe23RFxwbAmzqQn0BDRzJ6Qhx4WLQ2f
|
||||
QVhmDrvwF+VRshrp6bJKjcTZRmgIX3nVYAR0THuJu+zcB8de7G3lOH7YCl0rpboI
|
||||
fFkQxnTSt/MtU3FEJaajmz3PvzLkCI4FHFv8SouQ3ZIp/XRHk6luW0QWO3z6cy5l
|
||||
3V9BkhP0jkPpr9wfCZcmqu8EkCWZCfiu0Rf+k2uR2wo=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC+zCCAeWgAwIBAgIUPzR9NCfflP36Y/7nVoUjCbOTReswCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowHjEcMBoGA1UEAwwTbnNDZXJ0VHlwZSBDcml0aWNhbDCCASIwDQYJ
|
||||
MIIC+zCCAeWgAwIBAgIUQaNz+iusE21wkn6JJ/qLaB6Q8gEwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowHjEcMBoGA1UEAwwTbnNDZXJ0VHlwZSBDcml0aWNhbDCCASIwDQYJ
|
||||
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1
|
||||
SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+
|
||||
zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYL
|
||||
|
@ -9,10 +9,10 @@ K7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwc
|
|||
bJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibW
|
||||
JZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaM9
|
||||
MDswIwYDVR0RBBwwGoIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tMBQGCWCGSAGG
|
||||
+EIBAQEB/wQEAwIGQDALBgkqhkiG9w0BAQsDggEBAF0xKcPiDSPv5pPJYOtWPpoh
|
||||
7NaYXQjhx/J6c0W6gFvlEC5mkhaWxonLr5CRLzujLEKM0zzw8+J6mKnsdJbK7GxY
|
||||
4G0K1ymt49rsbxVEBtl9cbG6Cp155RYFThdKAj/f9EVEQgRqH2kzdtsvlljVgQtT
|
||||
EvDm0uhpBwzR13N+ZqStrVi8/SLUdXZnQxUNaFJzlggg/+AgfRi1dN5Da7P2t+0b
|
||||
pIG3MPzX7nxXBfqqb1MlA+Qn6kppdKWyzO60g++l4zfa/Z7PxIDsXJfhKgAbzWQ3
|
||||
hZi2k7P956QfLw0M6UfTl4pCFOMtENZdkqLQmEoa6KbcRvLPtb6ldqGPKoxa/Mc=
|
||||
+EIBAQEB/wQEAwIGQDALBgkqhkiG9w0BAQsDggEBAKWjJlobJfQhQxSNmvhokt1f
|
||||
rSWbHFyePtawqHSBKIOG9RrNB9E+nbDsI/gVvgVwi1GVu7cmg5SJDAuK19dpWXTh
|
||||
Pf4FPTm+FrLXwfPUOay5S3aGSwg29/PjnVayuBrJbMeYvtMJd7NGtadyv5wg3K3P
|
||||
SSFqYjUKOeWewt2NrX07LII68uctBja3BVpAPVvcoYsnR30ozuuiZTy6rBu0n4g0
|
||||
KU2stuuOnVLf7A7C2clj/ls0uX0hbSAaFH2RNQPsu+TL2ziSEEV9DYUm4pPMnpuO
|
||||
dhSDgTDkCTMqzS84FFTemzbkOUxBechMogtPkEhr157kbBXYzjytYgGLL7FGGRc=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDLzCCAhmgAwIBAgIUR/TVVDn0AzJEVj3V3p48mYE86n4wCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowLzEtMCsGA1UEAwwkbnNDZXJ0VHlwZSBDcml0aWNhbCBXaXRoIGV4
|
||||
MIIDLzCCAhmgAwIBAgIUL0RNPgFGtsQZxanRCa2IGPqVWZIwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowLzEtMCsGA1UEAwwkbnNDZXJ0VHlwZSBDcml0aWNhbCBXaXRoIGV4
|
||||
dEtleVVzYWdlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO
|
||||
FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr
|
||||
amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka
|
||||
|
@ -10,11 +10,11 @@ VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n
|
|||
aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE
|
||||
MdUDrNoYCjXtjQIDAQABo2AwXjAjBgNVHREEHDAagglsb2NhbGhvc3SCDSouZXhh
|
||||
bXBsZS5jb20wFAYJYIZIAYb4QgEBAQH/BAQDAgZAMAwGA1UdEwQFMAMBAQAwEwYD
|
||||
VR0lBAwwCgYIKwYBBQUHAwEwCwYJKoZIhvcNAQELA4IBAQAksxqbHtU7c2bXxhQF
|
||||
MASnpavCgexr/spzwzf1Slr4bj/Jz6ss8199B9CNuPcyZ2ufP23iqnrgJU1arxjk
|
||||
f3cxXr4PV4IgDsYbccBaNBWOc9+XnCTfvuE0yPOdZctbcfA6bey/phZNrVCWpFpa
|
||||
9D4aJesbmlm2MzSEKehjb3nL55UDO6iVNWYAB1MFFYzQGPUL2dmp5PgK6gYzMbjK
|
||||
VGQK4lyZZAgDR7bXAcKQPhT/ekKcYw7dbtbfm01/ELqqzIL7l/W6VlRO7xC8Htyn
|
||||
mlz3GNqNo73pIR41xHSHYAhjqwHtiIe8rZJyr4HqcSgaYZ0D6Js0PPT/k1saQq+r
|
||||
PHme
|
||||
VR0lBAwwCgYIKwYBBQUHAwEwCwYJKoZIhvcNAQELA4IBAQAO+rOEK3vhTmoLNg5w
|
||||
upxSODlCFghBLZ1qui7RWJME62JG/1sxZw4rHa0Pl2NP1U/Wy0ErAT/QQLyIahBL
|
||||
mjggdD3Vh9wfx4Qf4FwHGzJEopfsx6YQlHcXR1v5qb7lLeuywhA6m7agn9DWBGlg
|
||||
lLFNqtHmofQFaileQOA50Uu9qOAdbea5+rjZn9rBBvUUVeSc9hNWjDRCMk/5PSm4
|
||||
6ONpFjal4npPA8V/U7LleJR+VNbiCWNHaQD/9H+xBoay81m8GL0CdM9udBjbyf9W
|
||||
NlYtu87XanZn2//LghGGUW4HQn1YXWD6UeZngo91UdQeIOs+dCiTI8CldgpGafld
|
||||
8UdC
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC/DCCAeagAwIBAgIUKxdSO/ZfeYGpAf501TLycMrJEgQwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowIjEgMB4GA1UEAwwXbnNDZXJ0VHlwZSBOb3QgQ3JpdGljYWwwggEi
|
||||
MIIC/DCCAeagAwIBAgIUSeaDecTuqo807NV7Z4OGuTUEoKowCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowIjEgMB4GA1UEAwwXbnNDZXJ0VHlwZSBOb3QgQ3JpdGljYWwwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT
|
||||
2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV
|
||||
JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8N
|
||||
|
@ -9,10 +9,10 @@ jf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCA
|
|||
BiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh
|
||||
He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMB
|
||||
AAGjOjA4MCMGA1UdEQQcMBqCCWxvY2FsaG9zdIINKi5leGFtcGxlLmNvbTARBglg
|
||||
hkgBhvhCAQEEBAMCBkAwCwYJKoZIhvcNAQELA4IBAQBy7Hoo6D8JypxDVuTviT60
|
||||
hWKPY1prVr6uuyIokXqwGwWgw8ZQ0zAwo9zd5blM49ooKlZ0C/2DEY2fBXA+cpf8
|
||||
eZV0E1DiyNjOYSLpJQSj/lpn/isUGmQPFIyr9dnltSiAFPaT5LktrG+MPNs1Qitx
|
||||
wuXU7RKpGO52eiwxuFrwrFb0G0nAnItZncL+tgFRGb+pYK4BNxPIOmwHU+MxUF5O
|
||||
MsF1FHFYsy3cdihnA3+dGmmIAOLUtACZu3yxIT82AkXbLG9Ds9NIRXnC9+QO45B0
|
||||
eq4UzDdAxJSJIgIRsvuGqaN7oaxXBKv9J7PYCCn6RkiAYT1YDNJVmVdufMzQhZId
|
||||
hkgBhvhCAQEEBAMCBkAwCwYJKoZIhvcNAQELA4IBAQBUkcVO1xXJv8/BR5tUyQDt
|
||||
Y6gQMH9hfg2MZwR7mKj/ZdTEUMUqpOo4zfxRj8j3WNAF01g88D/oQw3IcDay9kpE
|
||||
EZDSLLQpVYW6l9xEWuCl+p9jNbFDmNxyPe2KOD+Pmp0ggkyeKyfC2l1cZS9kuQjW
|
||||
rIYgGdDVcXvBH/cfi8Dxl4IjWa/Fmkpw/W4uvcKcpLdtwZkGAa2CH1ymmeE3gtE8
|
||||
+uYJuWWP9RE1cwXtwoGTPoU2fxBP8V2gRgPrlHQlhlJzyWthJ30Cv+RBNU6IkzNT
|
||||
ZO10f39iPQScLbrcaDULX44vhUGhXlaXsOBWZnyX7exBWdUxNNpIjReO1nrZxufi
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDezCCAmWgAwIBAgIUHxXorgvSekn8KPmeXlYZnxM89m4wCwYJKoZIhvcNAQEL
|
||||
MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8y
|
||||
MDE3MDIwNDAwMDAwMFowJzElMCMGA1UEAwwcV3JvbmcgQ0EgUGluIFRlc3QgRW5k
|
||||
MIIDezCCAmWgAwIBAgIUNVbKGlj3T9hCc0QZzD1Zs4cFzeUwCwYJKoZIhvcNAQEL
|
||||
MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8y
|
||||
MDE4MDIwNTAwMDAwMFowJzElMCMGA1UEAwwcV3JvbmcgQ0EgUGluIFRlc3QgRW5k
|
||||
LUVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMF1xlJmCZ93
|
||||
CCpnkfG4dsN/XOU4sGxKzSKxy9RvplraKt1ByMJJisSjs8H2FIf0G2mJQb2ApRw8
|
||||
EgJExYSkxEgzBeUTjAEGzwi+moYnYLrmoujzbyPF2YMTud+vN4NF2s5R1Nbc0qbL
|
||||
|
@ -12,10 +12,10 @@ HhkdcSFo07sCAwEAAaOBrTCBqjB0BgNVHREEbTBrgigqLmluY2x1ZGUtc3ViZG9t
|
|||
YWlucy5waW5uaW5nLmV4YW1wbGUuY29tgigqLmV4Y2x1ZGUtc3ViZG9tYWlucy5w
|
||||
aW5uaW5nLmV4YW1wbGUuY29tghUqLnBpbm5pbmcuZXhhbXBsZS5jb20wMgYIKwYB
|
||||
BQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMAsG
|
||||
CSqGSIb3DQEBCwOCAQEAkQQFE0UqtrplaZqzvosJiLveVGfDGqRAjGCT3mimXUYt
|
||||
VuBXxYL66jQ2yq0pKKckQD/sZcgmToTGRwXCbErjIwM+IBgey7OBlCRNbkxUswCS
|
||||
DDk/80sIe1s0nCBs4BG0nG1PZMMayA277ExhdWlouTBvU2Xt5IieVN8yVNCi2bsX
|
||||
IGnLtQgt3naBPcMCGrjeKc+t3+mSnCzPIZTsx+faPJmTk5M2jwc75t5g/RUZOpf5
|
||||
ymNNq4OBIiHd9/bsmwEYrKetO99IEGNuWTcakM4bZ42WLXe7CJu/D8CLQhb9vCLG
|
||||
d4rTA2YmxNcsvV0d3TRoCALkBgc4Ho5dvaj/SXRplw==
|
||||
CSqGSIb3DQEBCwOCAQEArJqM6iooFNCAk11WMdPCxa4iGkG4V5zYuFjdd2K3LTLM
|
||||
ai5SZS875tXNol+YZgUh6cdTbVARdsB4saYGH1v5pAmK+VJniYQHWYsSLofgBfFw
|
||||
yAk1Ymj5pz8y6+ExYzWPBV5ihevtyCRPGG8xgZqRbERTdB2uBZGmQ441LLnZZZFX
|
||||
BByEFQ4M7qYmOTZaIxncSGZbwVncBYkLbYmOIPdcahVtnK1mIm1q7ET0KeUEPTLB
|
||||
5UEdNa7bd5ULWeCIVZxRWdawzktWdF7CfBVO2KeWiEE6wkL1Y3N29mUOynWKRs7w
|
||||
wo5ETwxEw/6UqOaGCmbCTN5Xa+N+ZE5/4g0gEEcFUg==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDdTCCAl+gAwIBAgIUa2BV5DHcAA84YP7Zdf4TnA4LUIcwCwYJKoZIhvcNAQEL
|
||||
MIIDdTCCAl+gAwIBAgIUOZxBsWqmNkNX1bk4vwjN7oalyxcwCwYJKoZIhvcNAQEL
|
||||
MDMxMTAvBgNVBAMMKFRlc3QgU2VsZi1zaWduZWQgRW5kLWVudGl0eSB3aXRoIENB
|
||||
IHRydWUwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIwNDAwMDAwMFowMzExMC8G
|
||||
IHRydWUwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowMzExMC8G
|
||||
A1UEAwwoVGVzdCBTZWxmLXNpZ25lZCBFbmQtZW50aXR5IHdpdGggQ0EgdHJ1ZTCC
|
||||
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9
|
||||
PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3
|
||||
|
@ -12,10 +12,10 @@ lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C
|
|||
AwEAAaOBgDB+MAwGA1UdEwQFMAMBAf8wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUF
|
||||
BzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMDoGA1UdEQQzMDGCL3NlbGYtc2ln
|
||||
bmVkLWVuZC1lbnRpdHktd2l0aC1jQS10cnVlLmV4YW1wbGUuY29tMAsGCSqGSIb3
|
||||
DQEBCwOCAQEAB2PEVMfffGy2JQjo1kaiVt6U1eI0tSTTntk7GqhgUo/JRIikqy3v
|
||||
E2m/oM6Xb/uP7kgd+DjCfJR75WmB8pldR8s/PFJWPzjhKdVPj+q++yw7mR+Z58sp
|
||||
YMmanGzGAZ+S3/MEP+tOX2COf5kt1CyrWOn3hGsedXkYlROzLrMfoFQ2ZAW82Qs2
|
||||
NoN5DYxcv2x9lEY+mez4mwPXMXFfYZgOqqvv1c8f/yykStvHMPMgFgjhA5+PV8Xz
|
||||
EvhGHXAZ+/EIBw+ypZaWrg+DhWrFrjnqT/DUSUsddGnoe/Ehkwj8WI3gD7yohT0h
|
||||
lijn0+4KSM6a+jHQqhQ+P/dy+t9vPDdvSw==
|
||||
DQEBCwOCAQEAOOiI4FYCOj5N75+ix87qQQjtyG//CTUi8SMRAIG9sQId7fRtXAcl
|
||||
qEtWKxdcNy4RYVoEQTNPrY6gr9amiPEpZ9IobtX1WW8gJiVj3EFLfXBKTE3B6Kxp
|
||||
Qim7bJvrqoumLgXtH7eljHdfN86I6Xnyk7L4tl30UhlOSd24jiQ8T5FxF7lcmEnT
|
||||
w+AthUUhOyKyDRXvV3jUpM3SKv6mz0rzm19A/qBOYM6Q+bAS5n47d/TPbmCff8T/
|
||||
zKU/Su7WYXsw7gU208DhWrqLjpUzPuGSRRTZgHCG35KpOlNcN81iZsvEYIyL+b68
|
||||
G2rlSZK2C3LaGi/0t7s3O8gUep20KSF7WA==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDgzCCAm2gAwIBAgIUReMvQBqE9q6NmzO14X6J+pL1vGwwCwYJKoZIhvcNAQEL
|
||||
MIIDgzCCAm2gAwIBAgIUV9yIaHMDuAdDCVBEzuEE5tSGIncwCwYJKoZIhvcNAQEL
|
||||
MDUxMzAxBgNVBAMMKlNlbGYtc2lnbmVkIEluYWRlcXVhdGUgRUtVIFRlc3QgRW5k
|
||||
LWVudGl0eTAiGA8yMDE0MTEyNzAwMDAwMFoYDzIwMTcwMjA0MDAwMDAwWjA1MTMw
|
||||
LWVudGl0eTAiGA8yMDE1MTEyODAwMDAwMFoYDzIwMTgwMjA1MDAwMDAwWjA1MTMw
|
||||
MQYDVQQDDCpTZWxmLXNpZ25lZCBJbmFkZXF1YXRlIEVLVSBUZXN0IEVuZC1lbnRp
|
||||
dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI
|
||||
BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa
|
||||
|
@ -12,10 +12,10 @@ aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK
|
|||
Ne2NAgMBAAGjgYowgYcwCwYDVR0PBAQDAgQwMBMGA1UdJQQMMAoGCCsGAQUFBwMB
|
||||
MC8GA1UdEQQoMCaCJHNlbGZzaWduZWQtaW5hZGVxdWF0ZUVLVS5leGFtcGxlLmNv
|
||||
bTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6
|
||||
ODg4OC8wCwYJKoZIhvcNAQELA4IBAQBULgN+U1uYk+FAGSUtSubSdAbSEzUAKUTn
|
||||
IEtowgow4y8oK0SmWOmlUCMuV3c6w9NYOX+JsYoyv9mw/Krz4hb4jAU9EdiS83xX
|
||||
qWc3l0CVbC704jaBBxsf6ZTrYCV+QgCCERlyThEBHUBAq2ROZ62FviWyAI8RDI07
|
||||
gOpKYf/+OfJ0BmWRX89Kmc9jgniWzEGBninxsN4fNsXldxw+Ppd78JBXneDOqgRd
|
||||
5v1iGABilqYUjAHHT+i5W70ItTMlHkQS9Jj6gOgad7tncoDzPGN+LIyLtIuQeWEU
|
||||
V4Q19gANGu/TqfSFgFPxu1k0G54mnBe5ShIC9QrdBySsecY3VSjH
|
||||
ODg4OC8wCwYJKoZIhvcNAQELA4IBAQAhtt1BOrCjch5fzJ+OIvqSF2qERDB7CJDA
|
||||
avhypMbCVCEabM1JBD8vtA5U7izjWpAJVlOwFBUPtGpeCtXkCZEyy6/JPOdc5hhJ
|
||||
1h0+c9CeKkmjwyydqqz3v4quXAI0WX7ChuO5WfsVY1swFcp6TYtGYBsjMVpVQaTw
|
||||
CGNFZ73EEksRWP0NH/SKABo+6dlvOghivAa3Wx1HEOVTFUo8u6odwZ596Xl/IhY4
|
||||
I0G/GuGCwMhBE/5GGpSI8qH8DxRXT7nrvdHZmuiRB2SJYeuF4Cs08KHO+ymiST/d
|
||||
OLnAKR1WWgslQbxZu3zdBDqKuKf2vOKS9xo6sQXP3TsLsSPxY1v2
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDMzCCAh2gAwIBAgIUdQJiAD83CKuJB6rEOWBo8c/zQ/owCwYJKoZIhvcNAQEL
|
||||
MCYxJDAiBgNVBAMMG1NlbGYtc2lnbmVkIFRlc3QgRW5kLWVudGl0eTAiGA8yMDE0
|
||||
MTEyNzAwMDAwMFoYDzIwMTcwMjA0MDAwMDAwWjAmMSQwIgYDVQQDDBtTZWxmLXNp
|
||||
MIIDMzCCAh2gAwIBAgIUFdYBQ3rk5hXCs0Bz6ERmayqrMTYwCwYJKoZIhvcNAQEL
|
||||
MCYxJDAiBgNVBAMMG1NlbGYtc2lnbmVkIFRlc3QgRW5kLWVudGl0eTAiGA8yMDE1
|
||||
MTEyODAwMDAwMFoYDzIwMTgwMjA1MDAwMDAwWjAmMSQwIgYDVQQDDBtTZWxmLXNp
|
||||
Z25lZCBUZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG
|
||||
m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr
|
||||
|
@ -10,11 +10,11 @@ SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3
|
|||
/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z
|
||||
FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjWTBXMCEGA1UdEQQaMBiCFnNlbGZz
|
||||
aWduZWQuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZo
|
||||
dHRwOi8vbG9jYWxob3N0Ojg4ODgvMAsGCSqGSIb3DQEBCwOCAQEAFdjt0c2Y0HDs
|
||||
Go+YRBmSPqOoqj6F0G/UukXLBc8AgiRKeygMZ7EcKcNEwPRnurWDxKqrQ4URJva9
|
||||
1sNS8RSVy4XBBZpxYNXqnmoKqFZbnhZ2GAvlbPfRHGya+NmaPr2PFPbdCGaZBVAB
|
||||
tirKJ3uHRH0OzohWgSqnBnGaZNYiyiaFap/sJavvhWhjJMPZxlo41a73yq+7p6Uy
|
||||
l8N5Oyq1/kuSMqDZpTnSjW6j9/Qs0BGbbixnTWPbvF5Gkz0LZCkpYpGFtmDgBbmL
|
||||
5owmw32ypwwHns8BSTmjDRbC/lb99KmxP2/Tgmvocn/yZdsUyx0s89ddNbLtj7Qw
|
||||
915Hd8Wmnw==
|
||||
dHRwOi8vbG9jYWxob3N0Ojg4ODgvMAsGCSqGSIb3DQEBCwOCAQEAiPY8Ka4thJkS
|
||||
6HzgnIpJyd09rmAls/LwAPRwhk8s652FEEGpZzkreDjOJ9LGYx01JWGQPDxOgddt
|
||||
ynYtbZVzwnSuJnISglU/mAsmgG47hSeBamOm9zg2KAC1+64nVgpkmYMEDGQC4h79
|
||||
cADh5g5ay0E47x/9u7F02z4ovXyJCDC/bOTFKv4WCkHEaIKhnbrv4EGT+lkfCFol
|
||||
obLR6h4mwclIDycIR9D2hg4ZSrnace1JzF0OALMVshwtclmJMS4yH+yACSeovT6t
|
||||
fN1CTvLAY8nYtyuxWc3D/gv0T5MWVvkSSfbrvt+nCUvrEsLFnDgKqMzh7S/iph3M
|
||||
UyeHQjtRIQ==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,18 +1,18 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICzzCCAbmgAwIBAgIUf80CD8/4YEbWhwYeA2isocegVpwwCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8yMDE3MDIw
|
||||
NDAwMDAwMFowEjEQMA4GA1UEAwwHVGVzdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
MIICzzCCAbmgAwIBAgIUH9DaznYx1NE1Cu9I8cBqxV9VgF4wCwYJKoZIhvcNAQEL
|
||||
MBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw
|
||||
NTAwMDAwMFowEjEQMA4GA1UEAwwHVGVzdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl
|
||||
qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg
|
||||
w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx
|
||||
V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1
|
||||
MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs
|
||||
vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUw
|
||||
AwEB/zALBgNVHQ8EBAMCAQYwCwYJKoZIhvcNAQELA4IBAQAhh2tjd37eSIBrm2fA
|
||||
Zd2thIyIID5tjQOnqx5dG/Spn2exJNMYaFMP88wu7CZA5UbKIjpkLTZH/t+96DZq
|
||||
0jVSybCl4MmBVsoxguoGVzSrByPtcVQTjX/W35ysQMB/sbQjqb9C/ecL2rBtqWxa
|
||||
H6mIuU9qyUZgBKyTXylPEdGmNWm7CJ3RCVMFtzS6+JLgAhpemPFwj/sF57rMfiiK
|
||||
X3v8yjqthq09qzv7XUP1PreScv72xkYlX+HsdlPfZ8xLokJoOLs0/qm3LKS4cIou
|
||||
v+WeqFWkct60qi42/3dBrnoD0LUP6CNmbJYmSNT8OfNSqx8bUSF3MsAdcVC/jIQf
|
||||
NYS/
|
||||
AwEB/zALBgNVHQ8EBAMCAQYwCwYJKoZIhvcNAQELA4IBAQA1o3GayNFRlVTrsoj2
|
||||
Ag06YatbGe94M/FT0MXngjlmrMkGZqHaDlrii7Jz+JP16CBjaIZ0ZP7I56Nn/l8y
|
||||
/kfe++zvr1uwRaKjtRGBiFpCjx10rI508wzSnOox3+bOtv9qjYaY7UjkBV3F40IS
|
||||
P8qKMtNspsR4tjS/D1jbculhngkPqhskefZFQQvcgG54L5j921GFKNeeX6i9QAzV
|
||||
jjM6i/iQYpAWCuh5+CetwUnfFuZCM80npp/qHMESkT3PyPpwqT9A5K+xQdVfpXq5
|
||||
SmVy5+QGWALuSV1sfIRXRwOh+2jCWwWPbyi9TlHrvlO5mL38qikdYBDPat3ve4cq
|
||||
5viq
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDpTCCAo+gAwIBAgIUfcZIUGx9/FiLBGq+1T5dtIJIicgwCwYJKoZIhvcNAQEL
|
||||
MCYxJDAiBgNVBAMMG1Rlc3QgSW50ZXJtZWRpYXRlIHRvIGRlbGV0ZTAiGA8yMDE0
|
||||
MTEyNzAwMDAwMFoYDzIwMTcwMjA0MDAwMDAwWjAuMSwwKgYDVQQDDCNUZXN0IEVu
|
||||
MIIDpTCCAo+gAwIBAgIUHccbzbbSEhGlmiWbLlfHcRQFD7MwCwYJKoZIhvcNAQEL
|
||||
MCYxJDAiBgNVBAMMG1Rlc3QgSW50ZXJtZWRpYXRlIHRvIGRlbGV0ZTAiGA8yMDE1
|
||||
MTEyODAwMDAwMFoYDzIwMTgwMjA1MDAwMDAwWjAuMSwwKgYDVQQDDCNUZXN0IEVu
|
||||
ZC1lbnRpdHkgZnJvbSB1bmtub3duIGlzc3VlcjCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl
|
||||
qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg
|
||||
|
@ -13,10 +13,10 @@ BIGAMH6CGXVua25vd25pc3N1ZXIuZXhhbXBsZS5jb22CNHVua25vd25pc3N1ZXIu
|
|||
aW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb22CK3Vua25vd25p
|
||||
c3N1ZXIudGVzdC1tb2RlLnBpbm5pbmcuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEE
|
||||
JjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMAsGCSqGSIb3
|
||||
DQEBCwOCAQEAuk4lvtvQf2IkgzGdnJUHfbpSE+B3aWwMY5yi2a5A6mx4lcMS4tsH
|
||||
3CI905S2GeLrs7iLd8qAZWsV4dlGr2/aNfTZMo824cSyj80StyMx37jMdC7+zXhY
|
||||
YhSiLZ1oLm1OMF95w3E+Nie/lf/VsIzlpmi8rAfnSLao/nWPKn8VEbotBOFyn/+Q
|
||||
qIQ026reZ3zURoNN1LMyJqSSApQoUSZZQh4OIuiSDkwh1TfxZHSdBVCM9OTju7q0
|
||||
rEqLX1ibnJv5pr7jMSwVGqP4ye1giz+cInIkCs+/l57hsx2cr97Q3vb/n4VoHZlA
|
||||
/2J3ikUU80aIEV5Cgj4yxZTDQ7fR+m8uZQ==
|
||||
DQEBCwOCAQEAjvk1a9yDZSYDNilWlvRcUk6stPfmjG7p0Owu0a+Lh8JIxOZXflZ1
|
||||
/hpVp0L5ds6mc74Q5VBJgqpkrpYBIVDPa3LJzW4HX8y7FtDo71Ca/ob+Xyc4hFdg
|
||||
3G2DqLePZXqkV+h6bsg/Rqv2FUt/GbUmv4sIkTwL5KgMEjLJGxwRTyrQZJlTMC5N
|
||||
uSxtWiCv+wLnP9NbkMgBHE1NnBQjF5nR/mJC7HUGykGYe+oJHuozq+/VCn3bXFUm
|
||||
kq9YXS0R84LcQH7gHtOlp5xwxiYXPH3C2cxobaJNdo5qsyOZYc5Diq/ukCN5rg0N
|
||||
5IOg9SPThtEzlCjTFRVHKE7ncgo7JxJ3gw==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,7 +1,7 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDNDCCAh6gAwIBAgIUN8wiHkr2t4HgCMoCqp+Gw/vrOrkwCwYJKoZIhvcNAQEL
|
||||
MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0EwIhgPMjAxNDExMjcwMDAwMDBaGA8y
|
||||
MDE3MDIwNDAwMDAwMFowMDEuMCwGA1UEAwwlVGVzdCBFbmQtZW50aXR5IHdpdGgg
|
||||
MIIDNDCCAh6gAwIBAgIUC7+ekJBbfCa4+95t1Lc9QFnFM00wCwYJKoZIhvcNAQEL
|
||||
MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0EwIhgPMjAxNTExMjgwMDAwMDBaGA8y
|
||||
MDE4MDIwNTAwMDAwMFowMDEuMCwGA1UEAwwlVGVzdCBFbmQtZW50aXR5IHdpdGgg
|
||||
dW50cnVzdGVkIGlzc3VlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG
|
||||
8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V
|
||||
|
@ -10,11 +10,11 @@ gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3
|
|||
0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz
|
||||
/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNeMFwwJgYDVR0RBB8wHYIbdW50cnVzdGVk
|
||||
aXNzdWVyLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW
|
||||
aHR0cDovL2xvY2FsaG9zdDo4ODg4LzALBgkqhkiG9w0BAQsDggEBAAvrVXj3ZPVc
|
||||
xxcuz9zDwU4NSaNTwtf+p4dVLN9LN/zewgvrKUtT7+v7CtAky8hlD8QRFTgtiLsl
|
||||
XwPUWQtFqJikLe/ukQTkFtYAnZPunTt+s6Tyi2xqRFm8RwdvZv/9KRky2z7in2+Q
|
||||
z12srCdiNBZhPP4lR7Q+PZoIR487cnbmiDknK1aHnjimMW0XfOagdF3mR4MHU2ST
|
||||
0UHZaQ6Hwg453ZUuEvo9/+yQSCcmt3DUdAge0uV3M9v5OajzRTVNlWfcNfmQBxUi
|
||||
Aoafr/f8Esq9pefqfB+gfW31IhP+CQtxrVw5dv3MGrK8cnVck37umOwHqYDh26s9
|
||||
Xnp8KC7ijy8=
|
||||
aHR0cDovL2xvY2FsaG9zdDo4ODg4LzALBgkqhkiG9w0BAQsDggEBADoMA0m+eXNs
|
||||
tdp2WpRyK3F9+FXIYbZGdlQFi+G9Dku/8J/cysb3jnN7zdSiCwkSJ38XR/8z4M0O
|
||||
x4i3/alFWP1HTvQmVOwP7U31u1h56QlS8ltFasZtd+lOELWvaj9WzG2glcFGTynT
|
||||
iIIl3LCm47O6u501xZsp5XPRaeY9956vuP7TwVIx8v2JR5H3hFhk9fR/mhR8QCOB
|
||||
HVu/iW9ux7g/9Up1Fi5mYAq6cmArpJ2LzEr57gdV1lfgKObTE++ZWtRa5N+zMZGX
|
||||
TU6WARBPH+vVHC1VKxY2SYENxswFtkgCSVoRFzn7sj/8jQ6iaJ86sf9poK0NrHdg
|
||||
P0ybC9Y8juA=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,17 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICqzCCAZUCFDX+15ASjo+0HtUTwYoepyZiQ6bbMAsGCSqGSIb3DQEBCzASMRAw
|
||||
DgYDVQQDDAdUZXN0IENBMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MIICqzCCAZUCFDt6FYWPwMbZVlZa329PtAVVBtsnMAsGCSqGSIb3DQEBCzASMRAw
|
||||
DgYDVQQDDAdUZXN0IENBMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
||||
MDBaMBIxEDAOBgNVBAMMB1YxIENlcnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9
|
||||
sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5
|
||||
TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7
|
||||
xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd
|
||||
tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l
|
||||
8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZIhvcNAQELA4IBAQCh
|
||||
jm9EQwLVxTNm5pQc78MVuaHXgKUmgukbdlfMJf5Hf1wUwwA26YVzOrvSTg3XSnO9
|
||||
1OZBJgZkwI0xZZe3r7ZgHNOkCz/OcIJENPBROHTms2RkL2Vc8Q/9JjBjh6Eh7QIN
|
||||
fSROi93QjSAqfiV95ymWqzxb2FD9CHUzKq/94uYsdr89rvjthw1/vaSx6ZaD21uM
|
||||
zTyL7rj7dQ63NiJZ82REqBmgZh/1Ha+RoLxWeEOA6RNE1I4nMapT5qDcXlq5Iiw/
|
||||
MPkpsbMfElWYIWklSfZU93HVTf+zLHlol7I/NauMxyoGO5tYjlIE2sfmtAv5vva6
|
||||
iw9NV8XL6V8C9d9L15gI
|
||||
8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZIhvcNAQELA4IBAQCW
|
||||
fJUaT3AtmftAlBtS3e1hs6V1XoQNaeSiff8PR6ootvISg5MpU1b2whEvNalJCUMD
|
||||
zBXkM7y3ERSgAvROu+CbBFOrOTPPStg88iZFm4WDrgotADxepbYd+x3IOL0vGq7F
|
||||
vcqdiQCRuhVRoopipqmowWF4KZtm0SnXoce7GnDhIjLtGxwz+zq3ls/2MrdaxdpL
|
||||
ggRkBUNfbTmDMvsjc3GxFHsXuX5cJUKVM2V8x5gNvtDBINiavy8HyQjhwSyTprRM
|
||||
KBConOKsh/WntsiakcsefVpc9kAR6DJjVvhFmLqHBUMrpBtDf5pb2JVgp/qn0oCw
|
||||
YqD30umtSUWyZaW1I1Nh
|
||||
-----END CERTIFICATE-----
|
|
@ -21,6 +21,7 @@ TEST_DIRS += [
|
|||
'test_cert_trust',
|
||||
'test_cert_version',
|
||||
'test_certDB_import',
|
||||
'test_content_signing',
|
||||
'test_ev_certs',
|
||||
'test_getchain',
|
||||
'test_intermediate_basic_usage_constraints',
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче