Úniky k RDNA 3 a 4 a Nvidia Lovelace. Navi 33 se 128bit. pamětí rychlejší než RX 6900 XT?

1. 10. 2021

Sdílet

 Autor: AMD
Sešla se poměrně zajímavá snůška informací o next-gen grafikách AMD (ale i Nvidie), které vyjdou příští rok. Vypadá to, že 5nm čipy a čiplety by mohly být největší revoluce v grafikách za mnoho let dozadu.

Zatím je ještě hodně brzo na to, abychom měli nějaké konkrétní informace o grafikách příští generace, GeForce RTX 4000 „Lovelace“ od Nvidie a Radeonech RX 7000 (architektura RDNA 3) jsou ještě jeden rok daleko. Přesto zdá se přece jen prosakují nějaké zvěsti, Je otázka, jak moc mohou v této fázi být věrné, ale možná bude zajímavé se na ně podívat. Mezi informacemi o RDNA 3 jsou ale i drobky k RDNA 4 a také k Nvidia Lovelace.

Zdrojem těchto informací je leaker Greymon55, jenž je uvedl jednak v tweetu, jednak ve svém „CV“ popisu, který pak ale odebral (nicméně byl mezitím „vyfocen“). Greymon55 toho v poslední době „unikává“ hodně a je v tom sice nový a neosvědčený, ale podle VideoCardz jde o „převlečený“ účet někoho, kdo už se ve „leakování“ etabloval předtím. Tyto zprávy je ovšem jako vždy nutné brát s rezervou. V tomto případě buďte opatrní ještě víc než obvykle a pamatujte, že se tyto zvěsti nemusí vyplnit.

Highend: Navi 31

Greymon55 tvrdí, že nejvýkonnější GPU v rodině RDNA 3/Radeon RX 7000 bude Navi 31. Jde ovšem spíše než o čip o kombinaci čipletů. Prý je u něj totiž použitý 5nm (pro výpočetní čiplety) a současně také 6nm proces (asi pro I/O čiplet). Toto GPU má prý mít 256bitovou paměťovou sběrnici a zatím netušíme, zda to bude jedna společná sběrnice pro všechny čiplety, nebo třeba GPU bude mít dva – nebo možná spíš tři, viz dále – čiplety, kde každý bude provozovat svoje vlastní 256bitové paměti.

Technologie pamětí by snad měla pořád být GDDR6, ne novější GDDR6X, na kterou má možná Nvidia exkluzivitu, není totiž standardizovaná. Pokud by paměti byly efektivně 16,0GHz, tak by toto GPU pořád mělo propustnost jen 512 GB/s jako Radeon RX 6800/6800 XT/6900 XT. AMD by mu ale asi dodalo větší Infinity Cache, která se ukázala v současné generaci Radeonů vysoce účinná. Karty RDNA 2 konkurují grafikám Ampere s pomalu dvojnásobnými propustnostmi paměti. U RDNA 3 by Infinity Cache možná mohla být už 256 MB, ne-li větší, což by zvýšilo její hitrate a škálování na vyšší rozlišení.

V onom smazeném bio na Twitteru měl Greymon55 napsané, že Navi 31 by mohlo mít až 15 360 shaderů. To nicméně není úplně nová informace, toto se diskutovalo již v červenci. Je otázka, zda nakonec tento počet jednotek bude platit a nešlo třeba o chybu. Možná je to zatím spíše tip nebo odhad a ne úplně únik v pravém slova smyslu.

GPU AMD Navi 22 11 Předobrazy v nynější generaci: GPU AMD Navi 22 se 192bitovou sběrnicí (vpravo) v porovnání s čipem Navi 21 s 256bitovou sběrnicí (vlevo) (Zdroj: AMD)

Mainstream Navi 32, pořád s čiplety?

Pod tímto GPU, na němž může být založeno více modelů karet (třeba RX 7900 XT, RX 7800 XT) má údajně být druhé GPU Navi 32. To má mít 192bitovou sběrnici opět s GDDR6, což by implikovalo, že to bude už více mainstreamová karta – jako je teď Radeon RX 6700 XT. Jenže pořád prý půjde o čipletové řešení a údajně má také používat mix 5nm čipletů a 6nm čipletů (I/O čiplety).

Podle Greymona55 by prý možná mohlo toto GPU mít až něco okolo 10 000 shaderů, pořád by tedy mohlo mít masivně vyšší výkon než dnešní Radeon RX 6900 XT s 5120 shadery. Dávalo by smysl, aby ony 5nm čiplety byly sdílené kvůli ušetření nákladů – pak by možná tato verze mohla mít dva výpočetní čiplety a Navi 31 tři. Každý by pak mohl mít 5120 shaderů/80 CU, ale to je jenom naše spekulace.

Levné Navi 33: karta se 128bitovou pamětí trhající RX 6900 XT?

Kde to začíná být zvláštní, je nabídka už zřejmě pro levnější karty, GPU Navi 33. Toto už není čipletové řešení, ale patrně monolit. A nepůjde o 5nm GPU, AMD ho prý bude vyrábět na 6nm procesu. Možná kvůli výrobním nákladům, ale je zajímavé, že firma raději naportuje architekturu RDNA 3 na odlišný proces místo řešení, které by použilo 6nm I/O čiplet s 5nm čipletem z předchozích vyšších GPU (pokud má jeden výpočetní čipset těch 5120 shaderů, tak by zde stačil jeden).

Možná, že cena za čipletové řešení je taková, že se u jednočipletové konfigurace vyplatí se jí vyhnout vyrobením zcela separátního GPU. Možná, že čiplety nebudou moc výhodné z hlediska energetické efektivity a klidové spotřeby, takže nebudou moc dobře použitelné v noteboocích. To by mohl být důvod, proč by AMD chtělo mít v portfoliu zároveň i jedno úplně monolitické GPU.

GPU AMD Navi 23 1600 GPU AMD Navi 23 se 128bitovou sběrnicí v nynější generaci Radeonů (Zdroj: AMD)

Zajímavé jsou i údajné specifikace. Toto GPU by prý možná mohlo mít 4096 shaderů (64 CU). Ale údajně s nimi má dosahovat výkonu, jenž bude vyšší než má nynější 7nm highend, Radeon RX 6900 XT s 5120 shadery. To by bylo moc pěkné, zvlášť pokud by to bylo za nějakou zajímavou cenu a s nižší spotřebou, ideálně pod 200 W.

https://twitter.com/greymon55/status/1443191000051032073

Ovšem Toto 6nm GPU Navi 33 to prý má dosáhnout s paměťovou sběrnicí širokou jen 128 bitů! Tedy takovou, jakou dnes mají jen poměrně levné karty (nebo aspoň karty, které by měly být levné, kdyby nebylo kryptoměnové bubliny). Karta má pořád mít GDDR6, takže by propustnost její hlavní paměti byla jen 256 GB/s s 16GHz čipy (maximálně by to mohlo být 288 GB/s, kdyby AMD použilo 18GHz čipy GDDR6, ale ty asi pořád budou dost drahé).

Navi 33 tak bude ještě víc než dnešní Radeony spoléhat na efekt Infinity Cache. Aby se výkon alespoň v nižších rozlišeních (do 2560 × 1440 bodů) podařilo dostat nad úroveň Radeonu RX 6900 XT, jenž má paměti s dvojnásobnou propustností, možná by už toto GPU mohlo mít Infinity Cache navýšenou na těch 256 MB. Každopádně bude zajímavé vidět, jestli se tenhle kousek AMD podaří a jeho grafika bude svádět vyrovnané souboje s kartami, které mají 2× nebo 3× širší sběrnice.

Triumf Infinity Cache?

Už teď se zdá, že by koncepce Infinity Cache (nebo obecně řečeno použití cache s vysokou propustností a kapacitou) mohla být cesta vpřed, kterou se nakonec uberou všechny budoucí architektury GPU, podobně jako se před několika lety prosadila účinná delta komprese, poprvé uvedená u GPU Nvidia Maxwell. Pokud se u Navi 33 podaří dosáhnout uvedené ambiciózní cíle, asi to bude definitivní potvrzení.

https://twitter.com/greymon55/status/1439486356548325387

Nvidia Lovelace: AD102, AD103, AD104, AD106…

Greymon55 zmiňuje také něco k chystaným grafikám GeForce s budoucí architekturou Lovelace. Tam se až takovéto divočiny zdá se nechystají a koncepce se tolik měnit nebude. Nvidia zdá se zůstane u širokých sběrnic a GDDR6X – i když to neznamená, že Nvidia nemůže také třeba svoje cache zvětšit. Její GPU ale zdá se v generaci Lovelace budou monolitická, což by jí mohlo přinášet výkonnostní bonusy, zatímco Radeony RDNA 3 budou muset podobně jako čipletové Ryzeny překonávat určité neefektivity vznikající v čipletovém řešení.

https://twitter.com/greymon55/status/1439546873325363204

Greymon55 uvádí, že architektura Lovelace bude ze začátku obsahovat čipy AD102 (highend), AD103, AD104 a AD106, snad s podobnými určeními, jako mají stejně číslované čipy Ampere. Pak nejspíš přijdou ještě menší a levnější verze (AD107 a AD108?), ale ty prý zatím nemůže potvrdit, zatímco předchozí čtyři čipy ano. Podle předchozích úniků jsou GPU Lovelace vyráběné 5nm procesem TSMC, což by mohlo o dost zlepšit výkon na 1 watt proti 8nm procesu Samsungu.

Frekvence nad 2,2 GHz?

Highendový čip AD102 bude opět mít 384bitovou sběrnici s GDDR6X, což bude asi použito u GeForce RTX 4090, zatímco RTX 4080 by zase možná mohla být opižlaná na 320 bitů.

https://twitter.com/greymon55/status/1439486792332308481

Čipy Lovelace prý jinak také získají výkon proti Ampere mimo nějaká zlepšení IPC také lepšími takty. Frekvence AD102 prý budou vyšší než 2,2 GHz. Ale pozor. Pokud jsou toto takty, které Nvidia bude uvádět ve specifikacích, pak by Lovelace reálně mohlo boostovat ještě výš a možná bychom se bavili o herních frekvencích až někde okolo 2,5–2,7 GHz.

Více: GeForce RTX 4000 prý má mít až 2× výkon proti RTX 3090. Spotřeba ale také má být masivní

Čipy generace RDNA 4?

Tento leaker Greymon55 měl chvíli v popisce svého účtu na Twitteru ještě další věc. Sérii čísel 41 42 43 44 45, bez nějakého dalšího vysvětlení. Nicméně stálo to vedle informací o čipech Navi 33, Navi 32 a Navi 31. Je proto dost pravděpodobné, že i zde se jedná o označení GPU, a to čipů generace Navi 4x, tedy patrně GPU s architekturou RDNA 4, kterou ještě AMD sice nikde neohlásilo, ale nejspíš ji také chystá.

CV leakera Greymon55 na Twitteru CV leakera Greymon55 na Twitteru, patrně uvádějící GPU generace AMD RDNA 3 a RDNA 4 (Zdroj: Wildcracks)

Pokud jsou tyto informace (a naše interpretace) správné, pak tedy AMD chystá v generaci následující po RDNA 3 pět různých GPU: Navi 41, Navi 42, Navi 43, Navi 44 a Navi 45. šlo by o různě velké a výkonné odvozeniny architektury RDNA 4, možná již vyráběné na 3nm procesu. Pokud AMD zachová dvouletý interval mezi novými generacemi, pak by asi karty (Radeon RX 8000? Nebo už 9000?) mohly vyjít v druhé polovině roku 2024 až první polovině roku 2025. Ještě jsou tedy hodně daleko.

CIF25

Pět různých čipů (nebo čipletových řešení) je nárůst proti nynějším čtyřem (Navi 21 až 23 a ještě nevydané Navi 24), nemluvě o třeba jen jednom čipu Vega nebo třech Polarisech. Mohlo by to znamenat, že se AMD bude snažit získat víc z grafického trhu a víc se snažit konkurovat Nvidii, která v posledních letech vždy měla co do počtu vyráběných GPU výraznou výhodu a tím i efektivnější skladbu modelů, což také přispívalo k lepším ziskům. A lepší zisky znamenaly více peněz na vývoj většího množství čipů, kdežto omezený počet GPU vyvíjených AMD mohl mít zase opačný vliv. Tudíž pro AMD by bylo pozitivní, kdyby na trh dokázalo dodávat více variant GPU jako Nvidia, i když k vyrovnání sil s ní to samo stačit nebude.

Zdroje: Greymon55 (1, 2, 3, 4, 5), Wildcracks

Autor článku

Redaktor portálu Cnews.cz. Zaměřuje se na procesory, mobilní SoC, grafické karty, disky a další počítačový hardware. Profil autora →

'; 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 »