Parametry 6nm APU Rembrandt/Ryzen 6000 potvrzené: CPU, GPU, DDR5 a podpora USB4

22. 6. 2021

Sdílet

Ilustrační obrázek Autor: loriklaszlo – Depositphotos
Ilustrační obrázek
Unikly první parametry APU Rembrandt, z kterého se stane Ryzen 6000 pro notebooky a socket AM5. Už máme takty Embedded modelů naznačující přínosy 6nm procesu nebo to, jak rychlé bude integrované RDNA 2 GPU. Potvrzené je také USB4.

V pondělí jsme tu psali o tom, že desky s novým socketem AM5 pro procesory AMD, používající už DDR5, by prý měly vyjít už v druhém kvartálu příštího roku, kdy by se do nich jako první asi měly dostat procesory Ryzen 6000 „Rembrandt“, což budou APU s jádry Zen 3 a poprvé grafikou používajíc architekturu RDNA 2. Trošku nečekaně teď k těmto procesorům unikly detaily. Vydání je sice ještě daleko, ale ven se dostaly už kompletní parametry těchto APU pro sektor embedded, které by měly být velmi blízké notebookovým modelům, které AMD eventuálně vydá. Ale něco samozřejmě říkají i o desktopových.

Informace přinesl Patrick Schur na Twitteru, který má patrně přístup k materiálům pod NDA, soudě dle minulých průsaků, kterých se dopustil. Nyní potvrdil, že Rembrandt je 6nm procesor/APU s CPU jádry Zen 3 (zatím bez nějakého bez označení Zen 3+, nečekejte tedy nové funkce ani zvýšení IPC). Schur uvádí, co materiály AMD říkají o jeho embedded verzi Ryzen V3000. Ta má pouzdro typu BGA s označením FP7r2, pravděpodobně je ale velmi podobná budoucím mobilním Ryzenům 6000U a 6000H/HS pro notebooky. Křemík by měl být identický.

PCIe 4.0, DDR5-4800, USB4 potvrzené

Potvrzené jsou (čímž míníme, z dobrého zdroje, ne nezvratně/oficiálně) základní parametry. Rembrandt bude přesně dle uniklé roadmapy už podporovat PCI Express 4.0, u AMD to bude první APU s PCIe 4.0. Řadič bude mít 20 linek, ale pro samostatné GPU prý bude k dispozici pořád jen ×8.

Současně zřejmě půjde o první procesor AMD používající paměti DDR5, a to DDR5-4800. Je uvedeno, že řadič má čtyři kanály, ale pozor – to je ekvivalent dvou kanálů u DDR4. DDR5 totiž bude nově používat koncepci, kdy je každý modul DIMM či SODIMM rozdělený na dva kanály o šířce 32 bitů – ty ale dohromady dávají šířku 64 bitů jako měl doteď jeden kanál, toto tedy samo o sobě nezvýší propustnost (tu navýší až efektivní frekvence, jež je 4800 MHz, což by snad mělo znamenat 76,8 GB/s). Se 128bitovou DDR5-4800 je Rembrandt oficiálně na stejné úrovni, jako Intel Alder Lake. Embedded verze má podporu ECC, která u notebookové verze aktivní asi nebude.

Tip: Co přinesou paměti DDR5? Zlepšení pro výkon, až 8400 MHz, možná i ECC pro všechny

Procesor – přímo SoC, používaný bez přídavného čipsetu – má podporu pro dvojici 10Gb/s Ethernetů, což ale již podporovala předchozí embedded APU (jde asi o stejnou technologii, jako u embedded Epyců). Co je pro nás zajímavější, je ale to, že Schur potvrzuje, že procesor bude podporovat USB4 – jako asi první procesor/platforma AMD.

Procesor AMD Ryzen 5000 pro notebooky APU Cezanne v pouzdru BGA 1600 05 Procesor AMD Ryzen 5000 pro notebooky, APU Cezanne v pouzdru BGA (Zdroj: AMD)

Procesor má poskytovat dva porty USB4. Toto by se mělo týkat i notebookové verze, takže se na něj asi už můžete těšit alespoň u některých modelů, které vyjdou s Ryzeny 6000 v H1 2022. Zda se USB4 díky tomuto dostane i do desktopové platformy AM5, to zatím nevíme.

Tip: USB4 je hotovo a vydáno, otevřená verze Thunderboltu 3 pro všechny je konečně tady

Pořád osm jader, GPU se 768 shadery RDNA 2

Pokud jste dumali, zda by třeba v této generaci už AMD nemohlo do APU pustit víc jader, není tomu tak. Rembrandt je podle Schura stále osmijádro – toto je myslím potvrzeno poprvé. Jádra jsou stále Zen 3 (pravděpodobně beze změn), jak již bylo řečeno. Naopak integrovaná grafika bude mít novou architekturu RDNA 2. Na čipu bude 12 CU, takže maximální konfigurace je 768 shaderů (šestina 4608 shaderů v Radeonu RX 6800 XT, ovšem toto iGPU asi bude mít výkon snižován horšími takty, propustností paměti a TDP).

https://twitter.com/patrickschur_/status/1407044836637790212

Vypadá to také, že se nezmění L3 cache CPU části, stále je jí 16 MB jako v Cezanne. AMD zřejmě u Rembrandtu používá stejnou metodiku šetřící náklady a čas potřebný pro vývoj jako u Cezanne a nahrazuje jen část návrhu. Zatímco Cezanne použilo uncore a GPU z APU Renoir a nahradilo jádra CPU, Rembrandt použije stejná jádra CPU jako mělo Cezanne a zase nahradí uncore a GPU.

TDP je u modelů Ryzen Embedded V3000 nastavitelné buď na 15–30 W (ekvivalent mobilních modelů 6000U), nebo 35–54 W (modely odpovídající notebookovým Ryzenům 600H/HS).

Modely Ryzen Embedded V3000

Embedded verze bude navazovat na generaci V2000, což je derivát APU Renoir vydaný v listopadu. AMD v ní mělo čtyři modely, což by mohlo platit i zde, ale Schur zatím prozradil jen tři modely.

Prvním je šestijádrový model Ryzen Embedded V3516. Ten má TDP nastavitelné v rozsahu 15–30 W (což je zvýšení, modely V2000 používaly rozsah 10–25 W). Takt je uváděný 2,8 GHz v základu, což by asi mohlo být pro 30W TDP, maximální boost je 4,4 GHz. Pokud byste to porovnali s šestijádrovým mobilním Ryzenem 5 5600U, ten má maximální boost 4,2 GHz a základ 2,3 GHz (ten je pro 15W TDP, takže se to asi nedá srovnávat). Tento model bude mít ořezané GPU s jen 512 shadery RDNA 2 na 1,8 GHz. Takty GPU budou poměrně nízké (zatímco v samostatných 7nm GPU už AMD někdy šplhá i k 3 GHz), což by snad mohlo vést k dobré energetické efektivitě.

Dále máme dva osmijádrové modely. Ryzen Embedded V3718 má osm jader, 16 vláken s TDP zase 15–30 W, přičemž jeho základní takt bude 2,6 GHz (asi pro 30W TDP, protože 15W Ryzen 7 5800U má základ jen 1,9 GHz). Narostlo ale opět maximální jednovláknové turbo na 4,6 GHz, zatímco 15W top model řady Ryzen 5000U má maximální boost 4,4 GHz. Tento procesor už také má plně aktivní GPU se 768 shadery (12 CU), na taktu 2 GHz.

Ryzen Embedded V3748 je zatím jediný model v kategorii 35–54W TDP (který tedy můžeme brát jako predikci notebookové rodiny H). Má osm jader, 16 vláken a základní frekvenci 3,1 GHz. Toto by ale už asi mohla být základní frekvence pro 35W TDP a ne pro vyšší 54W hodnotu, protože v generaci 5000 má AMD 3,0 GHz u modelů Ryzen 9 5900HS a 5980HS – dostat 100 MHz navíc do stejného limitu by možná 6nm proces mohl dokázat. Maximální boost je 4,6 GHz, což je stejné jako u Ryzenu 9 5900HS, ale nižší, než 4,8 GHz u modelu 5980HS. Zde je tedy možné, že tento model neukazuje ještě maximální schopnosti APU Rembrandt, uvidíme, zda se třeba top modely pro notebooky nepodaří dostat na 4,9 nebo 5,0 GHz.

Tento Ryzen Embedded V3748 totiž ani nemá plně aktivní integrované GPU, to je ze 768 ořezané na 512 shaderů na taktu 1,9 GHz. Zda bude existovat i nějaký 35–54W model s plnotučnou grafikou, tedy ještě nevíme.

Ryzen Embedded V3000 (Rembrandt, BGA)
Model Jádra L3 Takt Turbo GPU: shadery Takt GPU TDP
V3748 8 (16 v.) 16 MB 3,1 GHz 4,6 GHz 512 (RDNA 2) 1,9 GHz 35-54 W
V3718 8 (16 v.) 16 MB 2,6 GHz 4,6 GHz 768 (RDNA 2) 2,0 GHz 15-30 W
V3516 6 (12 v.) 16 MB 2,8 GHz 4,4 GHz 512 (RDNA 2) 1,8 GHz 15-30 W

Hlavní přínos v iGPU, 6nm proces by mohl být menší bonus

To, že máme jen údaje pro embedded řadu V3000, neumožňuje plně říct, jaký přínos bude mít 6nm proces v noteboocích a zda v nich také narostou boosty (a základní frekvence). Z parametrů to ale vypadá, že nějaká šance by na to být mohla. Hlavní přínosy ale evidentně budou v integrovaném GPU. Vypadá to, že grafika RDNA 2 by mohla dosahovat obdobných frekvencí jako integrovaná Vega v Renoiru a Cezanne, ale v top modelech budou mít o 50 % víc výpočetních jednotek. K tomu by mohlo něco přidat to, že jedna jednotka RDNA 2 má při stejném taktu o něco vyšší výkon (to by mohlo dát až 10–20 % k dobru), i když samozřejmě teprve uvidíme, zda se zlepší také třeba síla ROP.

Na druhou stranu Rembrandt nemá mít Infinity Cache, takže přínos architektury RDNA 2 proti Vega by mohl být nižší než v samostatných Radeonech RX 6000. Samotná propustnost pamětí, kterou APU typicky bude mít k dispozici, by ale také mohla jít nahoru až o 50 %, jelikož místo DDR4-3200 by měly notebooky typicky snad mít DDR5-4800 (pokud ne LPDDR5). V grafickém výkonu by proto Rembrandt mohl docela bodovat a má slušné šance zase převzít „trůn“ nejlepšího integrovaného GPU od grafiky Iris Xe v procesorech Intel Tiger Lake. Výkon by mohl stačit i na grafiku v Alder Lake, pokud v ní Intel nepřidá další jednotky EU a zůstane na stávajících 768 shaderech (a vypadá to, že to tak bude).

tržek roadmapy AMD ukazující APU Rembrandt září 2020 Útržek roadmapy AMD ukazující APU Rembrandt, září 2020 (Zdroj: MebiuW)

USB4 by mohlo znamenat další významné funkční zlepšení a podle předchozích úniků by tyto procesory v integrované grafice (nebo samostatně?) už mohly mít i nějaký akcelerátor umělé inteligence či AI zpracování obrazu („CVML“). Jak velké bude mít schopnosti a pro co všechno se bude dát využít, ale zatím netušíme. Zatím je asi lepší krotit očekávání, protože by mohlo jít i o něco s nevelkým významem.

hacking_tip

AMD v posledních letech vydávalo nové notebookové procesory vždy začátkem roku na CES, takže mobilní Rembrandt by mohl být odhalen tam za nějakého šest a půl měsíce. Embedded Ryzen V3000 ale asi může trvat déle, mohl by vyjít o mnoho měsíců později třeba až v druhé polovině roku 2022.

Galerie: Úniky a roadmapy AMD o procesorech Ryzen 5000, 6000, 7000 a 8000

Zdroje: Patrick Schur (1, 2, 3, 4), VideoCardz

'; document.getElementById('preroll-iframe').onload = function () { setupIframe(); } prerollContainer = document.getElementsByClassName('preroll-container-iframe')[0]; } function setupIframe() { prerollDocument = document.getElementById('preroll-iframe').contentWindow.document; let el = prerollDocument.createElement('style'); prerollDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:20px;right:25px}"; videoContent = prerollDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('PREROLL sound allowed'); // setUpIMA(true); videoContent.volume = 1; videoContent.muted = false; setUpIMA(); }).catch(function () { console.log('PREROLL sound forbidden'); videoContent.volume = 0; videoContent.muted = true; setUpIMA(); }); } } function setupDimensions() { prerollWidth = Math.min(iinfoPrerollPosition.offsetWidth, 480); prerollHeight = Math.min(iinfoPrerollPosition.offsetHeight, 320); } function setUpIMA() { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Preroll advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = prerollWidth; // adsRequest.linearAdSlotHeight = prerollHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. prerollDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( prerollDocument.getElementById('adContainer'), videoContent); } function unmutePrerollAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } } function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(prerollWidth, prerollHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } function onAdEvent(adEvent) { const ad = adEvent.getAd(); console.log('Preroll event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: if (!ad.isLinear()) { videoContent.play(); } prerollDocument.getElementById('adContainer').style.width = '100%'; prerollDocument.getElementById('adContainer').style.maxWidth = '640px'; prerollDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); if (ad.isLinear()) { intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } prerollDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (prerollLastError === 303) { playYtVideo(); } break; case google.ima.AdEvent.Type.COMPLETE: if (ad.isLinear()) { clearInterval(intervalTimer); } playYtVideo(); break; } } function onAdError(adErrorEvent) { console.log(adErrorEvent.getError()); prerollLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { playYtVideo(); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoPrerollPosition.remove(); playPrerollAd(); } else { return false; } adVolume = 1; return true; } function onContentPauseRequested() { videoContent.pause(); } function onContentResumeRequested() { videoContent.play(); } function onActiveView() { if (prerollContainer) { const containerOffset = prerollContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (prerollPaused) { adsManager.resume(); prerollPaused = false; } return true; } else { if (!prerollPaused) { adsManager.pause(); prerollPaused = true; } } } return false; } function playYtVideo() { iinfoPrerollPosition.remove(); youtubeIframe.style.display = 'block'; youtubeIframe.src += '&autoplay=1&mute=1'; } }
'; document.getElementById('outstream-iframe').onload = function () { setupIframe(); } replayScreen = document.getElementById('iinfoOutstreamReplay'); iinfoOutstreamPosition = document.getElementById('iinfoOutstreamPosition'); outstreamContainer = document.getElementsByClassName('outstream-container')[0]; setupReplayScreen(); } function setupIframe() { outstreamDocument = document.getElementById('outstream-iframe').contentWindow.document; let el = outstreamDocument.createElement('style'); outstreamDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:-5px;right:25px}"; videoContent = outstreamDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; if ( location.href.indexOf('rejstriky.finance.cz') !== -1 || location.href.indexOf('finance-rejstrik') !== -1 || location.href.indexOf('firmy.euro.cz') !== -1 || location.href.indexOf('euro-rejstrik') !== -1 || location.href.indexOf('/rejstrik/') !== -1 || location.href.indexOf('/rejstrik-firem/') !== -1) { outstreamDirectPlayed = true; soundAllowed = true; iinfoVastUrlIndex = 0; } if (!outstreamDirectPlayed) { console.log('OUTSTREAM direct'); setUpIMA(true); } else { if (soundAllowed) { const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('OUTSTREAM sound allowed'); setUpIMA(false); }).catch(function () { console.log('OUTSTREAM sound forbidden'); renderBanner(); }); } } else { renderBanner(); } } } function getWrapper() { let articleWrapper = document.querySelector('.rs-outstream-placeholder'); // Outstream Placeholder from RedSys manipulation if (articleWrapper && articleWrapper.style.display !== 'block') { articleWrapper.innerHTML = ""; articleWrapper.style.display = 'block'; } // Don't render OutStream on homepages if (articleWrapper === null) { if (document.querySelector('body.p-index')) { return null; } } if (articleWrapper === null) { articleWrapper = document.getElementById('iinfo-outstream'); } if (articleWrapper === null) { articleWrapper = document.querySelector('.layout-main__content .detail__article p:nth-of-type(6)'); } if (articleWrapper === null) { // Euro, Autobible, Zdravi articleWrapper = document.querySelector('.o-article .o-article__text p:nth-of-type(6)'); } if (articleWrapper === null) { articleWrapper = document.getElementById('sidebar'); } if (!articleWrapper) { console.error("Outstream wrapper of article was not found."); } return articleWrapper; } function setupDimensions() { outstreamWidth = Math.min(iinfoOutstreamPosition.offsetWidth, 480); outstreamHeight = Math.min(iinfoOutstreamPosition.offsetHeight, 320); } /** * Sets up IMA ad display container, ads loader, and makes an ad request. */ function setUpIMA(direct) { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); if (direct) { adsRequest.adTagUrl = directVast; console.log('Outstream DIRECT CAMPAING advert: ' + directVast); videoContent.muted = true; videoContent.volume = 0; outstreamDirectPlayed = true; } else { adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Outstream advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; } // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = outstreamWidth; // adsRequest.linearAdSlotHeight = outstreamHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function setupReplayScreen() { replayScreen.addEventListener('click', function () { iinfoOutstreamPosition.remove(); iinfoVastUrlIndex = 0; outstreamInit(); }); } /** * Sets the 'adContainer' div as the IMA ad display container. */ function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. outstreamDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( outstreamDocument.getElementById('adContainer'), videoContent); } function unmuteAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } } /** * Loads the video content and initializes IMA ad playback. */ function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(outstreamWidth, outstreamHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } /** * Handles the ad manager loading and sets ad event listeners. * @param { !google.ima.AdsManagerLoadedEvent } adsManagerLoadedEvent */ function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } /** * Handles actions taken in response to ad events. * @param { !google.ima.AdEvent } adEvent */ function onAdEvent(adEvent) { // Retrieve the ad from the event. Some events (for example, // ALL_ADS_COMPLETED) don't have ad object associated. const ad = adEvent.getAd(); console.log('Outstream event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: // This is the first event sent for an ad - it is possible to // determine whether the ad is a video ad or an overlay. if (!ad.isLinear()) { // Position AdDisplayContainer correctly for overlay. // Use ad.width and ad.height. videoContent.play(); } outstreamDocument.getElementById('adContainer').style.width = '100%'; outstreamDocument.getElementById('adContainer').style.maxWidth = '640px'; outstreamDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); // This event indicates the ad has started - the video player // can adjust the UI, for example display a pause button and // remaining time. if (ad.isLinear()) { // For a linear ad, a timer can be started to poll for // the remaining time. intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } outstreamDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (outstreamLastError === 303) { if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } } break; case google.ima.AdEvent.Type.COMPLETE: // This event indicates the ad has finished - the video player // can perform appropriate UI actions, such as removing the timer for // remaining time detection. if (ad.isLinear()) { clearInterval(intervalTimer); } if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } break; } } /** * Handles ad errors. * @param { !google.ima.AdErrorEvent } adErrorEvent */ function onAdError(adErrorEvent) { // Handle the error logging. console.log(adErrorEvent.getError()); outstreamLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { renderBanner(); } } function renderBanner() { if (isBanner) { console.log('Outstream: Render Banner'); iinfoOutstreamPosition.innerHTML = ""; iinfoOutstreamPosition.style.height = "330px"; iinfoOutstreamPosition.appendChild(bannerDiv); } else { console.log('Outstream: Banner is not set'); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoOutstreamPosition.remove(); outstreamInit(); } else { return false; } adVolume = 1; return true; } /** * Pauses video content and sets up ad UI. */ function onContentPauseRequested() { videoContent.pause(); // This function is where you should setup UI for showing ads (for example, // display ad timer countdown, disable seeking and more.) // setupUIForAds(); } /** * Resumes video content and removes ad UI. */ function onContentResumeRequested() { videoContent.play(); // This function is where you should ensure that your UI is ready // to play content. It is the responsibility of the Publisher to // implement this function when necessary. // setupUIForContent(); } function onActiveView() { if (outstreamContainer) { const containerOffset = outstreamContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (outstreamPaused) { adsManager.resume(); outstreamPaused = false; } return true; } else { if (!outstreamPaused) { adsManager.pause(); outstreamPaused = true; } } } return false; } let outstreamInitInterval; if (typeof cpexPackage !== "undefined") { outstreamInitInterval = setInterval(tryToInitializeOutstream, 100); } else { const wrapper = getWrapper(); if (wrapper) { let outstreamInitialized = false; window.addEventListener('scroll', () => { if (!outstreamInitialized) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { outstreamInit(); outstreamInitialized = true; } } }); } } function tryToInitializeOutstream() { const wrapper = getWrapper(); if (wrapper) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { if (cpexPackage.adserver.displayed) { clearInterval(outstreamInitInterval); outstreamInit(); } } } else { clearInterval(outstreamInitInterval); } } }
OSZAR »