Page Not Found
We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..c2d09db93 Binary files /dev/null and b/.DS_Store differ diff --git a/404.html b/404.html index 6890c6382..ece4b9402 100644 --- a/404.html +++ b/404.html @@ -2,7 +2,7 @@
- +We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
Just your friendly neighborhood video embed site
\n \n\n'})}),"\n",(0,s.jsx)(i.p,{children:"< br />\nThese interactive sites usually deploy a live script, like a Javascript framework. Examples are NodeJS, ExpressJS, Svelte, etc. These are used to parse video and thumbnails realtime so they can be embedded on Discord (or potentially other platforms)."}),"\n",(0,s.jsx)(i.h3,{id:"discords-end",children:"Discord's End"}),"\n",(0,s.jsx)(i.p,{children:'Traditionally, Discord\'s media embedder will impose it\'s own video embed size limit (50 MiB) when a user sends a direct video link as usual. But in this case Discord will embed the thumbnail first, not the video. You could say the link "tricks" Discord by showing a "false face" first.'}),"\n",(0,s.jsx)(i.h2,{id:"strengths--limitations",children:"Strengths & Limitations"}),"\n",(0,s.jsx)(i.p,{children:"After a combination of countless hours of observation, rigorous testing throughout the period of a year, and conversations with the sites' creators, the current strengths & limitations of this exploit are enumerated below."}),"\n",(0,s.jsx)(i.h4,{id:"strengths",children:"Strengths"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["You can embed non-web compatible codecs such as ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/video/HEVC",children:"HEVC"})," in ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/introduction/terminology#mp4--m4v",children:"MP4/MOV"}),", but the user must be using a compatible browser. ",(0,s.jsx)(i.a,{href:"https://thorium.rocks",children:"Thorium"})," or Safari version 13 or greater will work for HEVC playback."]}),"\n",(0,s.jsx)(i.li,{children:"There is no maximum size. You could embed a video the size of a raw Bluray, although I do not condone this unless you have the necessary legal permissions to do so or you're uploading a Creative Commons licensed movie like Big Buck Bunny while adhering to the restrictions of the applicable Creative Commons license. This also means you can send high bitrate gaming clips to your friends without any restrictions, assuming you already have a place to upload them."}),"\n"]}),"\n",(0,s.jsx)(i.h4,{id:"limitations",children:"Limitations"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["You can only use ",(0,s.jsx)(i.a,{href:"https://simple.wikipedia.org/wiki/Hotlinking",children:"hotlinks"}),", which means direct linking to the video itself ending in the appropriate file extension such as ",(0,s.jsx)(i.code,{children:".mp4"}),". Cloud services like Google Drive or OneDrive will not work for storage."]}),"\n",(0,s.jsxs)(i.li,{children:["You cannot use Discord's CDN (cdn.discordapp.com) as the video source. I assume this is because of Discord's proxy blocking embeds over 50 MiB, but ",(0,s.jsx)(i.strong,{children:"only discord.nfp.is can do this"}),", as it ",(0,s.jsx)(i.strong,{children:"proxies cdn.discordapp.com"})," itself."]}),"\n",(0,s.jsx)(i.li,{children:"You cannot embed videos in any resolutions higher than 3840 x 2160, Discord imposes a hard limit for this on all video after it was discovered that some videos could play normally but then be maliciously scaled to ridiculous resolutions during playback to crash Discord."}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"differences-between-sites",children:"Differences between Sites"}),"\n",(0,s.jsx)(i.p,{children:"As mentioned before, there are five known sites at the time of writing. They all serve the same function, but one may interest you more than another due to slight differences in features & functionality."}),"\n",(0,s.jsx)(i.p,{children:"Here are the sites, each with one noteworthy special benefit:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.a,{href:"https://stolen.shoes",children:"https://stolen.shoes"})," - Recognition, as it is the OG."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.a,{href:"https://discord.nfp.is",children:"https://discord.nfp.is"})," - You can use Discord CDN as video source."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.a,{href:"https://embeds.video",children:"https://embeds.video"})," - Immediately input video source into the URL (",(0,s.jsx)(i.code,{children:"https://embeds.video/https://example.com/v/video.mp4"}),")"]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.a,{href:"https://x266.mov/discord-embed",children:"https://x266.mov/discord-embed"})," - Attractive domain, simple layout."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.a,{href:"https://autocompressor.net/av1",children:"https://autocompressor.net/av1"})," - Lots of info dump, pretty advanced features."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"That concludes the technical overview! Next, let's cover the history of this exploit."}),"\n",(0,s.jsx)(i.h2,{id:"the-lore",children:"The Lore"}),"\n",(0,s.jsx)(i.h3,{id:"dwayne",children:"Dwayne"}),"\n",(0,s.jsxs)(i.p,{children:["In around April of 2022, a Reddit user going by the name of u/CreativeGamer03 ",(0,s.jsx)(i.a,{href:"https://www.reddit.com/r/discordapp/comments/u96kky/someone_sent_this_in_the_memes_channel_and_bruh",children:"posted a video on r/discordapp"}),' of a link where a GIF of Dwayne "The Rock" Johnson plays caption with "Is this a GIF or is it a video?" When played, a low-quality music video of Rick Astley\'s "Never Gonna Give You Up" plays.']}),"\n",(0,s.jsxs)(i.p,{children:["The link used is now unfortunately ",(0,s.jsx)(i.a,{href:"https://archuser.de/the-rock",children:"removed"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"discovery",children:"Discovery"}),"\n",(0,s.jsxs)(i.p,{children:["On 23rd June 2022, a Discord user ",(0,s.jsx)(i.em,{children:"Clybius"})," on the AV1 Community server asked people for ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/video/VP9",children:"VP9"})," or ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/video/AVC",children:"H.264"})," videos that were over 100 MB in size. At the time the current 500 MB nitro tier did not exist. They then decided to use a 59 minute 1080p sample video of nature scenery from around the world with a thumbnail featuring a GIF of a waterfall to test the exploit. It worked."]}),"\n",(0,s.jsxs)(i.p,{children:["He tried shortly afterward with ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/video/AV1",children:"AV1"}),". Eureka, it also worked:"]}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"AV1",src:t(6364).A+"",width:"497",height:"421"})}),"\n",(0,s.jsx)(i.p,{children:"Clybius confirmed that this could be patched if discovered. He cites having had the idea from the Dwayne Johnson example above, but forgetting about it for a couple of months. So, it seems this entire concept stemmed from a silly rickroll."}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"Dwayne",src:t(3312).A+"",width:"1108",height:"98"})}),"\n",(0,s.jsx)(i.h3,{id:"the-experiments--interactive-site",children:"The Experiments & Interactive Site"}),"\n",(0,s.jsxs)(i.p,{children:["After the discovery of AV1 embedding, experimentation brought about the discovery that ",(0,s.jsx)(i.em,{children:"any"})," video codec will work as long as the user can decode/play the codec and the container/extension is an MP4, MOV, or WebM. These are all traditionally web-compatible containers. If you're interested in learning about containers, please see the ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/introduction/terminology#container",children:"Containers"})," section on the ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/introduction/terminology",children:"Terminology"})," page."]}),"\n",(0,s.jsxs)(i.p,{children:["This applies to HEVC, ProRes, ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/audio/AAC#xhe-aac",children:"xHE-AAC"}),", and other bizarre codecs that are rarely seen on the Web."]}),"\n",(0,s.jsxs)(i.p,{children:["While experimentating, Clybius converted one their idle domains ",(0,s.jsx)(i.code,{children:"stolen.shoes"})," into an interactive embedder that provided a textbox for a video URL, a thumbnail URL, a width value, & a height value for the desired video. This would be the first website for Discord embedding."]}),"\n",(0,s.jsx)(i.h3,{id:"virality",children:"Virality"}),"\n",(0,s.jsxs)(i.p,{children:["It's not long before people outside of the AV1 Community discovered ",(0,s.jsx)(i.code,{children:"stolen.shoes"}),", and its popularity increased rapidly. Its use usually involved the illicit distribution of full-length, unauthorized copies of movies; this sometimes happened very shortly after some movies were released. There were a couple notable instances of this happenening that caused quite the stir online each time."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:['The first instance featured the DreamWorks sequel of "Puss in Boots (2011)", "Puss in Boots: The Last Wish (2022)". A 1080p video sourced from a streaming site was the first wake up call that attracted attention to the existence of these embed sites. This example used ',(0,s.jsx)(i.code,{children:"stolen.shoes"}),"."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"puss",src:t(6689).A+"",width:"1088",height:"318"})}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:['The second instance was when highly-anticipated animated film "The Super Mario Bros. Movie (2023)" produced by Illumination, Universal Studios, and Nintendo was spread around Discord. It was first spotted as a Cam (A camera recording by someone in theaters), then as it went out on streaming services a different link appeared but spread faster and with upgraded 1080p quality. Both used ',(0,s.jsx)(i.code,{children:"stolen.shoes"})," as the embed site."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"mario",src:t(5716).A+"",width:"1307",height:"335"})}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:['The third instance is very recent as of the day this was posted. A streaming-service sourced "Five Nights at Freddy\'s (2023)" was spread around since the movie released both in theaters and streaming service (Peacock) day one, and it gained steam extremely fast as most people had not seen it yet. Currently, this illegal novelty is gaining ',(0,s.jsx)(i.a,{href:"https://www.reddit.com/r/discordapp/comments/17hx45y/is_discordnfp_an_ip_grabber/",children:"hundreds of upvotes within the r/discordapp subreddit"}),". The copy seems to be a compressed 720p encode. This example used ",(0,s.jsx)(i.code,{children:"discord.nfp.is"}),"."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"fnaf",src:t(3536).A+"",width:"1044",height:"409"})}),"\n",(0,s.jsx)(i.p,{children:"Note the ones listed here are the ones that I saw become extremely popular. There may be lesser known links that have been spread around privately or just did not cause enough noise for me to notice. Some less popular examples I've noticed, featuring more illicit copyrighted content distribution:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Top Gun Maverick (2022)"}),"\n",(0,s.jsx)(i.li,{children:"The SpongeBob trilogy (2005/2015/2020)"}),"\n",(0,s.jsx)(i.li,{children:"Spider-Man: Across the Spider-Verse (2023)"}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"closing",children:"Closing"}),"\n",(0,s.jsx)(i.p,{children:"The ability to embed unusually large videos on Discord has enabled both positive and negative use cases. On the one hand, it allows high-quality content to be shared easily among friends. However, it has also facilitated mass copyright infringement by empowering virtually anyone with a Discord accound to freely spread pirated movies."}),"\n",(0,s.jsx)(i.p,{children:"While this is fascinating from a technical perspective, embedding techniques like these tread a fine ethical line. As with anything, it is important to be mindful of how our actions affect others, and I should remind everyone that content creators deserve to be compensated for their work. As users, we should support them by accessing their content via legitimate platforms."}),"\n",(0,s.jsx)(i.p,{children:"It is hard to say how long this exploit will continue to be usable. Instead of enabling piracy, which may cause Discord to be more likely to patch this exploit if they see it as a serious threat, let's instead use these capabilities responsibly to share our own creations, gaming highlights, and other media which we can share legally. Given some thoughtfulness, perhaps we can find a fair balance between respecting copyright law and appeasing Discord's sensibilities while allowing some creative flexibility on the platform."}),"\n",(0,s.jsx)(i.p,{children:"Thank you for reading this blog post, I hope you learned something!"})]})}function c(e={}){const{wrapper:i}={...(0,n.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},6364:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/clybius-av1-28dcfefe8d58784301332b8119d2e926.webp"},3312:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/clybius-dwayne-15341f187cb8e7dbfd5c4ee00451eabd.webp"},9395:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/discord-embed-blog-image-2bcaf4f73f5fa33664328756753f3041.webp"},3536:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/discordnfpis-fnaf-dab5b24a63605605e7c7882d20a992a3.webp"},5716:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/stolenshoes-mario-6de3b4071d4c09064d7323fec40530f4.webp"},6689:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/stolenshoes-puss-842a1f9165b7571d293a74be89da25c2.webp"},8453:(e,i,t)=>{t.d(i,{R:()=>r,x:()=>a});var s=t(6540);const n={},o=s.createContext(n);function r(e){const i=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),s.createElement(o.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/09a8bfdb.b905f91a.js b/assets/js/09a8bfdb.b905f91a.js deleted file mode 100644 index 79740191d..000000000 --- a/assets/js/09a8bfdb.b905f91a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[5579],{1689:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>d,contentTitle:()=>r,default:()=>c,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var s=t(4848),n=t(8453);const o={title:"Embedding the Un-Embeddable",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",slug:"embedding-the-un-embeddable",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4"}],tags:["video","discord"],image:"/img/discord-embed-blog-image.webp",hide_table_of_contents:!1},r=void 0,a={permalink:"/blog/embedding-the-un-embeddable",source:"@site/blog/2023-10-29-embedding-the-un-embeddable copy.mdx",title:"Embedding the Un-Embeddable",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",date:"2023-10-29T00:00:00.000Z",tags:[{inline:!0,label:"video",permalink:"/blog/tags/video"},{inline:!0,label:"discord",permalink:"/blog/tags/discord"}],readingTime:8.92,hasTruncateMarker:!0,authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"}],frontMatter:{title:"Embedding the Un-Embeddable",description:"Revealing the secrets of those websites that allow you to embed entire movies, AV1, and videos over 500MB on Discord.",slug:"embedding-the-un-embeddable",authors:[{name:"Simulping",title:"Maintainer / Encoder",url:"https://github.com/Simulping",image_url:"https://avatars.githubusercontent.com/u/12994794?v=4",imageURL:"https://avatars.githubusercontent.com/u/12994794?v=4"}],tags:["video","discord"],image:"/img/discord-embed-blog-image.webp",hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Encoding Animation with SVT-AV1: A Deep Dive",permalink:"/blog/svt-av1-deep-dive"},nextItem:{title:"AV1 Encoding for Dummies",permalink:"/blog/av1-encoding-for-dummies"}},d={authorsImageUrls:[void 0]},l=[{value:"A Scenario",id:"a-scenario",level:2},{value:"But First, a Quick Disclosure",id:"but-first-a-quick-disclosure",level:2},{value:"How it Works",id:"how-it-works",level:2},{value:"The Website's End",id:"the-websites-end",level:3},{value:"Discord's End",id:"discords-end",level:3},{value:"Strengths & Limitations",id:"strengths--limitations",level:2},{value:"Strengths",id:"strengths",level:4},{value:"Limitations",id:"limitations",level:4},{value:"Differences between Sites",id:"differences-between-sites",level:2},{value:"The Lore",id:"the-lore",level:2},{value:"Dwayne",id:"dwayne",level:3},{value:"Discovery",id:"discovery",level:3},{value:"The Experiments & Interactive Site",id:"the-experiments--interactive-site",level:3},{value:"Virality",id:"virality",level:3},{value:"Closing",id:"closing",level:2}];function h(e){const i={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.img,{alt:"Feature image",src:t(5364).A+"",width:"1920",height:"1080"}),"\n",(0,s.jsx)(i.strong,{children:'A 567.14 MB, 12 min 11 s, 2K (2,048 x 858), VP9 + Opus, 6.51 Mbps average, Blender short film "Cosmos Laundromat"'})]}),"\n",(0,s.jsx)(i.h2,{id:"a-scenario",children:"A Scenario"}),"\n",(0,s.jsx)(i.p,{children:"While chatting in your favorite Discord servers & group chats, you may see a friend send a weird link. You might even consider it suspicious on first glance. It is a video featuring an image of a movie poster with a play button that is almost begging to be clicked. Naturally, you click it."}),"\n",(0,s.jsx)(i.p,{children:"It loads for a second, and to your surprise it is a full-length, 90-minute (sometimes even two hour)-long unauthorized copy of a movie. If you don't know exactly what is going on, you probably sit there dumbfounded as a pixel perfect HD movie plays back. You may have expected a stereotypically muddy, blocky, laggy shitpost, but this has defied your expectations."}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"stolen.shoes",src:t(5570).A+"",width:"1088",height:"318"})}),"\n",(0,s.jsxs)(i.p,{children:["The truth is, there are ",(0,s.jsx)(i.em,{children:"multiple"})," site that do this. Currently, there are five at the time of writing. Below is a list the ones I am currently familiar with:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"https://stolen.shoes",children:"https://stolen.shoes"})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"https://discord.nfp.is",children:"https://discord.nfp.is"})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"https://embeds.video",children:"https://embeds.video"})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"https://x266.mov/discord-embed",children:"https://x266.mov/discord-embed"})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"https://autocompressor.net/av1",children:"https://autocompressor.net/av1"})}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The big question is, ",(0,s.jsx)(i.strong,{children:"how do they work?"})," Let's get to dissecting."]}),"\n",(0,s.jsx)(i.h2,{id:"but-first-a-quick-disclosure",children:"But First, a Quick Disclosure"}),"\n",(0,s.jsx)(i.p,{children:"The Codec Wiki unequivocally condemns any form of piracy, including the unauthorized distribution of copyrighted content. This blog post is intended to educate & inform. You may not use the tools discussed to infringe upon the intellectual property rights of content creators without serious legal risk. We encourage our readers to respect copyright laws & use the tools we discuss here appropriately."}),"\n",(0,s.jsx)(i.h2,{id:"how-it-works",children:"How it Works"}),"\n",(0,s.jsx)(i.p,{children:"The entire scheme is actually very simple, as it is all just HTML meta tags (If you are familiar with web development, this is all a walk in the park)."}),"\n",(0,s.jsx)(i.p,{children:"The technology's inner working can be divided into two distinct parts. First, let's see how it works on the website's end."}),"\n",(0,s.jsx)(i.h3,{id:"the-websites-end",children:"The Website's End"}),"\n",(0,s.jsx)(i.p,{children:"If you view each website's source, you will find this specific line in each one but they may have a different order:"}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-html",children:'\n\n\n\n\n'})}),"\n",(0,s.jsxs)(i.p,{children:["These are the ",(0,s.jsx)(i.code,{children:"head"})," parts of HTML, which dictate metadata for the document itself such as what the website title/name is, cosmetic embed, defining the site's icon, etc. They are usually found in between the ",(0,s.jsx)(i.code,{children:""})," and ",(0,s.jsx)(i.code,{children:""})," tags. Here's an example of a static HTML site serving one specific video:"]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-html",children:'\n\n\n \n \nJust your friendly neighborhood video embed site
\n \n\n'})}),"\n",(0,s.jsx)(i.p,{children:"< br />\nThese interactive sites usually deploy a live script, like a Javascript framework. Examples are NodeJS, ExpressJS, Svelte, etc. These are used to parse video and thumbnails realtime so they can be embedded on Discord (or potentially other platforms)."}),"\n",(0,s.jsx)(i.h3,{id:"discords-end",children:"Discord's End"}),"\n",(0,s.jsx)(i.p,{children:'Traditionally, Discord\'s media embedder will impose it\'s own video embed size limit (50 MiB) when a user sends a direct video link as usual. But in this case Discord will embed the thumbnail first, not the video. You could say the link "tricks" Discord by showing a "false face" first.'}),"\n",(0,s.jsx)(i.h2,{id:"strengths--limitations",children:"Strengths & Limitations"}),"\n",(0,s.jsx)(i.p,{children:"After a combination of countless hours of observation, rigorous testing throughout the period of a year, and conversations with the sites' creators, the current strengths & limitations of this exploit are enumerated below."}),"\n",(0,s.jsx)(i.h4,{id:"strengths",children:"Strengths"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["You can embed non-web compatible codecs such as ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/video/HEVC",children:"HEVC"})," in ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/introduction/terminology#mp4--m4v",children:"MP4/MOV"}),", but the user must be using a compatible browser. ",(0,s.jsx)(i.a,{href:"https://thorium.rocks",children:"Thorium"})," or Safari version 13 or greater will work for HEVC playback."]}),"\n",(0,s.jsx)(i.li,{children:"There is no maximum size. You could embed a video the size of a raw Bluray, although I do not condone this unless you have the necessary legal permissions to do so or you're uploading a Creative Commons licensed movie like Big Buck Bunny while adhering to the restrictions of the applicable Creative Commons license. This also means you can send high bitrate gaming clips to your friends without any restrictions, assuming you already have a place to upload them."}),"\n"]}),"\n",(0,s.jsx)(i.h4,{id:"limitations",children:"Limitations"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["You can only use ",(0,s.jsx)(i.a,{href:"https://simple.wikipedia.org/wiki/Hotlinking",children:"hotlinks"}),", which means direct linking to the video itself ending in the appropriate file extension such as ",(0,s.jsx)(i.code,{children:".mp4"}),". Cloud services like Google Drive or OneDrive will not work for storage."]}),"\n",(0,s.jsxs)(i.li,{children:["You cannot use Discord's CDN (cdn.discordapp.com) as the video source. I assume this is because of Discord's proxy blocking embeds over 50 MiB, but ",(0,s.jsx)(i.strong,{children:"only discord.nfp.is can do this"}),", as it ",(0,s.jsx)(i.strong,{children:"proxies cdn.discordapp.com"})," itself."]}),"\n",(0,s.jsx)(i.li,{children:"You cannot embed videos in any resolutions higher than 3840 x 2160, Discord imposes a hard limit for this on all video after it was discovered that some videos could play normally but then be maliciously scaled to ridiculous resolutions during playback to crash Discord."}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"differences-between-sites",children:"Differences between Sites"}),"\n",(0,s.jsx)(i.p,{children:"As mentioned before, there are five known sites at the time of writing. They all serve the same function, but one may interest you more than another due to slight differences in features & functionality."}),"\n",(0,s.jsx)(i.p,{children:"Here are the sites, each with one noteworthy special benefit:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.a,{href:"https://stolen.shoes",children:"https://stolen.shoes"})," - Recognition, as it is the OG."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.a,{href:"https://discord.nfp.is",children:"https://discord.nfp.is"})," - You can use Discord CDN as video source."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.a,{href:"https://embeds.video",children:"https://embeds.video"})," - Immediately input video source into the URL (",(0,s.jsx)(i.code,{children:"https://embeds.video/https://example.com/v/video.mp4"}),")"]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.a,{href:"https://x266.mov/discord-embed",children:"https://x266.mov/discord-embed"})," - Attractive domain, simple layout."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.a,{href:"https://autocompressor.net/av1",children:"https://autocompressor.net/av1"})," - Lots of info dump, pretty advanced features."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"That concludes the technical overview! Next, let's cover the history of this exploit."}),"\n",(0,s.jsx)(i.h2,{id:"the-lore",children:"The Lore"}),"\n",(0,s.jsx)(i.h3,{id:"dwayne",children:"Dwayne"}),"\n",(0,s.jsxs)(i.p,{children:["In around April of 2022, a Reddit user going by the name of u/CreativeGamer03 ",(0,s.jsx)(i.a,{href:"https://www.reddit.com/r/discordapp/comments/u96kky/someone_sent_this_in_the_memes_channel_and_bruh",children:"posted a video on r/discordapp"}),' of a link where a GIF of Dwayne "The Rock" Johnson plays caption with "Is this a GIF or is it a video?" When played, a low-quality music video of Rick Astley\'s "Never Gonna Give You Up" plays.']}),"\n",(0,s.jsxs)(i.p,{children:["The link used is now unfortunately ",(0,s.jsx)(i.a,{href:"https://archuser.de/the-rock",children:"removed"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"discovery",children:"Discovery"}),"\n",(0,s.jsxs)(i.p,{children:["On 23rd June 2022, a Discord user ",(0,s.jsx)(i.em,{children:"Clybius"})," on the AV1 Community server asked people for ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/video/VP9",children:"VP9"})," or ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/video/AVC",children:"H.264"})," videos that were over 100 MB in size. At the time the current 500 MB nitro tier did not exist. They then decided to use a 59 minute 1080p sample video of nature scenery from around the world with a thumbnail featuring a GIF of a waterfall to test the exploit. It worked."]}),"\n",(0,s.jsxs)(i.p,{children:["He tried shortly afterward with ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/video/AV1",children:"AV1"}),". Eureka, it also worked:"]}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"AV1",src:t(169).A+"",width:"497",height:"421"})}),"\n",(0,s.jsx)(i.p,{children:"Clybius confirmed that this could be patched if discovered. He cites having had the idea from the Dwayne Johnson example above, but forgetting about it for a couple of months. So, it seems this entire concept stemmed from a silly rickroll."}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"Dwayne",src:t(7131).A+"",width:"1108",height:"98"})}),"\n",(0,s.jsx)(i.h3,{id:"the-experiments--interactive-site",children:"The Experiments & Interactive Site"}),"\n",(0,s.jsxs)(i.p,{children:["After the discovery of AV1 embedding, experimentation brought about the discovery that ",(0,s.jsx)(i.em,{children:"any"})," video codec will work as long as the user can decode/play the codec and the container/extension is an MP4, MOV, or WebM. These are all traditionally web-compatible containers. If you're interested in learning about containers, please see the ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/introduction/terminology#container",children:"Containers"})," section on the ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/introduction/terminology",children:"Terminology"})," page."]}),"\n",(0,s.jsxs)(i.p,{children:["This applies to HEVC, ProRes, ",(0,s.jsx)(i.a,{href:"https://wiki.x266.mov/docs/audio/AAC#xhe-aac",children:"xHE-AAC"}),", and other bizarre codecs that are rarely seen on the Web."]}),"\n",(0,s.jsxs)(i.p,{children:["While experimentating, Clybius converted one their idle domains ",(0,s.jsx)(i.code,{children:"stolen.shoes"})," into an interactive embedder that provided a textbox for a video URL, a thumbnail URL, a width value, & a height value for the desired video. This would be the first website for Discord embedding."]}),"\n",(0,s.jsx)(i.h3,{id:"virality",children:"Virality"}),"\n",(0,s.jsxs)(i.p,{children:["It's not long before people outside of the AV1 Community discovered ",(0,s.jsx)(i.code,{children:"stolen.shoes"}),", and its popularity increased rapidly. Its use usually involved the illicit distribution of full-length, unauthorized copies of movies; this sometimes happened very shortly after some movies were released. There were a couple notable instances of this happenening that caused quite the stir online each time."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:['The first instance featured the DreamWorks sequel of "Puss in Boots (2011)", "Puss in Boots: The Last Wish (2022)". A 1080p video sourced from a streaming site was the first wake up call that attracted attention to the existence of these embed sites. This example used ',(0,s.jsx)(i.code,{children:"stolen.shoes"}),"."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"puss",src:t(5570).A+"",width:"1088",height:"318"})}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:['The second instance was when highly-anticipated animated film "The Super Mario Bros. Movie (2023)" produced by Illumination, Universal Studios, and Nintendo was spread around Discord. It was first spotted as a Cam (A camera recording by someone in theaters), then as it went out on streaming services a different link appeared but spread faster and with upgraded 1080p quality. Both used ',(0,s.jsx)(i.code,{children:"stolen.shoes"})," as the embed site."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"mario",src:t(3397).A+"",width:"1307",height:"335"})}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:['The third instance is very recent as of the day this was posted. A streaming-service sourced "Five Nights at Freddy\'s (2023)" was spread around since the movie released both in theaters and streaming service (Peacock) day one, and it gained steam extremely fast as most people had not seen it yet. Currently, this illegal novelty is gaining ',(0,s.jsx)(i.a,{href:"https://www.reddit.com/r/discordapp/comments/17hx45y/is_discordnfp_an_ip_grabber/",children:"hundreds of upvotes within the r/discordapp subreddit"}),". The copy seems to be a compressed 720p encode. This example used ",(0,s.jsx)(i.code,{children:"discord.nfp.is"}),"."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.img,{alt:"fnaf",src:t(9769).A+"",width:"1044",height:"409"})}),"\n",(0,s.jsx)(i.p,{children:"Note the ones listed here are the ones that I saw become extremely popular. There may be lesser known links that have been spread around privately or just did not cause enough noise for me to notice. Some less popular examples I've noticed, featuring more illicit copyrighted content distribution:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Top Gun Maverick (2022)"}),"\n",(0,s.jsx)(i.li,{children:"The SpongeBob trilogy (2005/2015/2020)"}),"\n",(0,s.jsx)(i.li,{children:"Spider-Man: Across the Spider-Verse (2023)"}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"closing",children:"Closing"}),"\n",(0,s.jsx)(i.p,{children:"The ability to embed unusually large videos on Discord has enabled both positive and negative use cases. On the one hand, it allows high-quality content to be shared easily among friends. However, it has also facilitated mass copyright infringement by empowering virtually anyone with a Discord accound to freely spread pirated movies."}),"\n",(0,s.jsx)(i.p,{children:"While this is fascinating from a technical perspective, embedding techniques like these tread a fine ethical line. As with anything, it is important to be mindful of how our actions affect others, and I should remind everyone that content creators deserve to be compensated for their work. As users, we should support them by accessing their content via legitimate platforms."}),"\n",(0,s.jsx)(i.p,{children:"It is hard to say how long this exploit will continue to be usable. Instead of enabling piracy, which may cause Discord to be more likely to patch this exploit if they see it as a serious threat, let's instead use these capabilities responsibly to share our own creations, gaming highlights, and other media which we can share legally. Given some thoughtfulness, perhaps we can find a fair balance between respecting copyright law and appeasing Discord's sensibilities while allowing some creative flexibility on the platform."}),"\n",(0,s.jsx)(i.p,{children:"Thank you for reading this blog post, I hope you learned something!"})]})}function c(e={}){const{wrapper:i}={...(0,n.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},169:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/clybius-av1-28dcfefe8d58784301332b8119d2e926.webp"},7131:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/clybius-dwayne-15341f187cb8e7dbfd5c4ee00451eabd.webp"},5364:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/discord-embed-blog-image-2bcaf4f73f5fa33664328756753f3041.webp"},9769:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/discordnfpis-fnaf-dab5b24a63605605e7c7882d20a992a3.webp"},3397:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/stolenshoes-mario-6de3b4071d4c09064d7323fec40530f4.webp"},5570:(e,i,t)=>{t.d(i,{A:()=>s});const s=t.p+"assets/images/stolenshoes-puss-842a1f9165b7571d293a74be89da25c2.webp"},8453:(e,i,t)=>{t.d(i,{R:()=>r,x:()=>a});var s=t(6540);const n={},o=s.createContext(n);function r(e){const i=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),s.createElement(o.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/09bc817a.2cf169f0.js b/assets/js/09bc817a.a9273c21.js similarity index 99% rename from assets/js/09bc817a.2cf169f0.js rename to assets/js/09bc817a.a9273c21.js index acecb54d1..9409e1c06 100644 --- a/assets/js/09bc817a.2cf169f0.js +++ b/assets/js/09bc817a.a9273c21.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[1554],{5811:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var s=i(4848),o=i(8453);const t={title:"Opus",sidebar_position:2},a="Opus",r={id:"audio/Opus",title:"Opus",description:"The content in this entry is incomplete & is in the process of being completed.",source:"@site/docs/audio/Opus.mdx",sourceDirName:"audio",slug:"/audio/Opus",permalink:"/docs/audio/Opus",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/audio/Opus.mdx",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Opus",sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"AAC",permalink:"/docs/audio/AAC"},next:{title:"Dolby Digital",permalink:"/docs/audio/Dolby"}},c={},d=[{value:"Format Breakdown",id:"format-breakdown",level:2},{value:"SILK",id:"silk",level:3},{value:"CELT",id:"celt",level:3},{value:"Encoders",id:"encoders",level:2},{value:"Opusenc",id:"opusenc",level:3},{value:"FFopus",id:"ffopus",level:3},{value:"vac-enc",id:"vac-enc",level:3}];function l(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",br:"br",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"opus",children:"Opus"}),"\n",(0,s.jsx)(n.admonition,{title:"Under Maintenance",type:"info",children:(0,s.jsx)(n.p,{children:"The content in this entry is incomplete & is in the process of being completed."})}),"\n",(0,s.jsxs)(n.p,{children:["Opus is an open-source audio codec that has largely replaced ",(0,s.jsx)(n.a,{href:"/docs/audio/Vorbis",children:"Vorbis"})," as the standard open audio codec. It is the recommended codec for usage in WebM video containers in tandem with the ",(0,s.jsx)(n.a,{href:"/docs/video/VP9",children:"VP9"})," or ",(0,s.jsx)(n.a,{href:"/docs/video/AV1",children:"AV1"})," video codecs."]}),"\n",(0,s.jsxs)(n.p,{children:["Opus is known for its incredible coding efficiency and unique multi-channel optimizations. Stereo Opus audio reaches ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Transparency_(data_compression)",children:"transparency"})," (psychoacoustically lossless audio quality) at 128kb/s, compared to ",(0,s.jsx)(n.a,{href:"/docs/audio/AAC",children:"AAC"}),"'s generally agreed upon 256kb/s and ",(0,s.jsx)(n.a,{href:"/docs/audio/MP3",children:"MP3"}),"'s 320kb/s. Transparency varies based on the type of content & the encoding implementation used, especially for codecs other than Opus, and the values provided above may be debated to a degree."]}),"\n",(0,s.jsxs)(n.p,{children:["Opus is described on ",(0,s.jsx)(n.a,{href:"https://opus-codec.org/",children:"opus-codec.org"}),' as a "totally open, royalty-free, highly versatile audio codec. Opus is unmatched for interactive speech and music transmission over the Internet, but is also intended for storage and streaming applications. It is standardized by the Internet Engineering Task Force (IETF) as ',(0,s.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc6716",children:"RFC 6716"}),' which incorporated technology from Skype\u2019s SILK codec and Xiph.Org\u2019s CELT codec."']}),"\n",(0,s.jsx)(n.p,{children:"Opus supports the following features:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Bitrates from 6 kb/s to 510 kb/s (with a maximum of around 255 kb/s per channel on non stereo layouts)"}),"\n",(0,s.jsx)(n.li,{children:"Sampling rates from 8 kHz (narrowband) to 48 kHz (fullband)"}),"\n",(0,s.jsx)(n.li,{children:"Frame sizes from 2.5 ms to 60 ms"}),"\n",(0,s.jsx)(n.li,{children:"Support for both constant bitrate (CBR) and variable bitrate (VBR)"}),"\n",(0,s.jsx)(n.li,{children:"Audio bandwidth from narrowband to fullband"}),"\n",(0,s.jsx)(n.li,{children:"Support for speech and music"}),"\n",(0,s.jsx)(n.li,{children:"Support for mono and stereo"}),"\n",(0,s.jsx)(n.li,{children:"Support for up to 255 channels (multistream frames)"}),"\n",(0,s.jsx)(n.li,{children:"Dynamically adjustable bitrate, audio bandwidth, and frame size"}),"\n",(0,s.jsx)(n.li,{children:"Good loss robustness and packet loss concealment (PLC)"}),"\n",(0,s.jsx)(n.li,{children:"Floating point and fixed-point implementation"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"via opus-codec.org and wiki.hydrogenaud.io"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"format-breakdown",children:"Format Breakdown"}),"\n",(0,s.jsx)(n.p,{children:"Opus is a hybrid audio codec, composed of two codecs as mentioned above. These are Skype's SILK codec for voice & Xiph.Org's CELT codec. Opus's initial name, Harmony, may have been because of the \"harmony\" of these two codecs and the musical connotation of harmony."}),"\n",(0,s.jsx)(n.h3,{id:"silk",children:"SILK"}),"\n",(0,s.jsx)(n.p,{children:"SILK, initially from Skype, was designed to be used for voice calls on Microsoft products like Skype. The first stable release of the codec was in 2009, and since then it has been freely licensed under the BSD 2-Clause license which has allowed for its adoption into Opus. The version of SILK used in Opus is substantially modified from - and not compatible with - the standalone SILK codec previously described here."}),"\n",(0,s.jsx)(n.p,{children:"SILK is optimized for speech, and so has limited sample rates as follows:"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Narrowband: 3-4000hz\nMediumband: 3-6000hz\nWideband: 3-8000hz"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"SILK's latency is 10 to 60ms based on the desired framesize + 5ms lookahead to estimate noise shaping + (potentially) 1.5ms sampling rate conversion overhead if the input audio needs to be resampled."}),"\n",(0,s.jsx)(n.h3,{id:"celt",children:"CELT"}),"\n",(0,s.jsx)(n.p,{children:'Much like SILK, CELT is under the BSD 2-Clause license. The preview release came out in 2011. CELT stands for "Code-Excited Lapped Transform" and was designed to be the true successor to Vorbis, even being dubbed as "Vorbis II" during its initial development as part og Xiph.Org\'s "Ghost" project in 2005.'}),"\n",(0,s.jsxs)(n.p,{children:["CELT was designed to be a full-band general purpose codec without a particular specialization for a certain kind of audio, making it distinctly different from Xiph's ",(0,s.jsx)(n.a,{href:"/docs/audio/Speex",children:"Speex"})," codec & more similar to Vorbis. It is computationally simple relative to competing codec technologies like ",(0,s.jsx)(n.a,{href:"/docs/audio/AAC",children:"AAC"})," & even Vorbis, enabling extremely low latency that is competitive with ",(0,s.jsx)(n.a,{href:"/docs/audio/AAC#aac-ld--aac-eld",children:"AAC-LD"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"CELT can work with the following sample rates:"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Narrowband: 3-4000hz\nMediumband: 3-6000hz\nWideband: 3-8000hz\nSuperWideband: 3-12000hz\nFullband: 3-20000hz"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"encoders",children:"Encoders"}),"\n",(0,s.jsx)(n.h3,{id:"opusenc",children:"Opusenc"}),"\n",(0,s.jsxs)(n.p,{children:["Opus's reference encoder is ",(0,s.jsx)(n.a,{href:"https://github.com/xiph/opus",children:"opusenc"}),", which is known for its fantastic performance and versatility. It is licensed under the BSD 3-clause license as part of the reference libopus library. There are a myriad of options that may be used to encode with opusenc, but the utility is considered to have sane encoding defaults for local storage & playback. The best options will be outlined below."]}),"\n",(0,s.jsxs)(n.p,{children:["Usage: ",(0,s.jsx)(n.code,{children:"opusenc [options] input_file output_file.opus"})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--bitrate #.###"})," Sets the overall target bitrate in kbit/s. Most encoders use ",(0,s.jsx)(n.em,{children:"bits"}),' per second, meaning you have to specify "128K" for 128kbit/s for example. Opus doesn\'t follow this, so you\'d just have to type "128" though keep in mind using efficient VBR encoding means the final bitrate may be different than the target. Opus supports bitrates from 6 kb/s to 510 kb/s.']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--vbr"})," Tells the encoder to encode using a variable bit rate, allocating more or less bits when necessary to preserve overall fidelity per bit. This is the best option for local storage & playback, and is ",(0,s.jsx)(n.em,{children:"enabled by default."})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--cvbr"})," Tells the encoder that it is allowed to vary the bitrate like with VBR, but it must constrain the maximum bitrate at any given moment to the value provided."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--hard-cbr"})," Tells the encoder to use a constant bitrate the whole time."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--music"})," & ",(0,s.jsx)(n.code,{children:"--speech"})," Forces the AI content-detector built into opusenc to treat the input as either speech or music. The bitrate range where this is relevant is around 12-40kb/s."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--comp #"})," Sets the encoder complexity to a value from 0 to 10, 0 being the least complex & 10 being the most. ",(0,s.jsx)(n.em,{children:"The default is 10."})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--framesize #"})," Sets the maximum encoder frame size in milliseconds. Lowering this is useful for improving latency at the expense of audio quality per bit. It is worth noting that 40 & 60ms framesizes are just multiple 20ms frames stitched together via opusenc's default behavior, and are not considered useful as they just lower the encoder's adaptability which can worsen both latency & coding efficiency. ",(0,s.jsx)(n.em,{children:"The default value is 20."})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--expect-loss #"})," Percentage value for expected packet loss. Not useful for local encoding & playback, but useful for real-time applications. ",(0,s.jsx)(n.em,{children:"Default value is 0."})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--downmix-mono"})," Downmixes multiple channels into a single channel."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--downmix-stereo"})," Downmixes multiple channels into two channels, left & right, given more than two channels are provided to the encoder."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--no-phase-inv"})," Disables phase inversion. Helpful when downmixing stereo to mono, although this is the default behavior in that scenario since libopus 1.3. Slightly decreases stereo audio quality."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--max-delay #"})," Sets maximum container delay in milliseconds, from 0-1000. ",(0,s.jsx)(n.em,{children:"Default is 1000."})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Looking at the default values for the encoder flags, opusenc almost always follows the best practices for every default value. This makes it very easy to use, and it is as simple as plugging in a source of some kind and using only the most basic commands to encode with opus."}),"\n",(0,s.jsx)(n.p,{children:"An example opusenc command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'opusenc "input.wav" "output.opus" --bitrate 96\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/docs/utilities/ffmpeg",children:"FFmpeg"})," using libopus:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'ffmpeg -i "input.flac" -c:a libopus -b:a 128K "output.ogg"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you'd like to learn more about opusenc & its recommended default behavior, read this article on ",(0,s.jsx)(n.a,{href:"https://wiki.xiph.org/Opus_Recommended_Settings#Bandwidth_Transition_Thresholds",children:"Opus Recommended Settings"}),"."]}),"\n",(0,s.jsxs)(n.admonition,{title:"Existing bug in ffmpeg",type:"info",children:[(0,s.jsxs)(n.p,{children:["Due to a bug in ffmpeg ",(0,s.jsx)(n.a,{href:"https://trac.ffmpeg.org/ticket/5718",children:"(#5718)"}),", ffmpeg won't automatically remap ",(0,s.jsx)(n.code,{children:"5.1(side)"})," to ",(0,s.jsx)(n.code,{children:"5.1"})," when using libopus.",(0,s.jsx)(n.br,{}),"\n","To remap the channel layout explicitly, try this:"]}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'ffmpeg -i "input.flac" -c:a libopus -af aformat=channel_layouts=5.1 "output.ogg"\n'})}),(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsx)(n.p,{children:"You can handle arbitrary audio stream mappings with this:"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"-af aformat=channel_layouts=7.1|5.1|stereo -mapping_family 1\n"})})]})]}),"\n",(0,s.jsx)(n.h3,{id:"ffopus",children:"FFopus"}),"\n",(0,s.jsx)(n.p,{children:"FFopus is an experimental native opus encoder from FFmpeg. It is not widely regarded as providing any decent uplift in coding efficiency compared to libopus, and is usually considered worse; its only merit is being able to handle 5.1(side) streams while libopus in FFmpeg cannot. It only implements the CELT part of the Opus codec."}),"\n",(0,s.jsx)(n.p,{children:"FFopus usage:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'ffmpeg -i "input.wma" -c:a opus -b:a 128K -strict -2 "output.opus"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"vac-enc",children:"vac-enc"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/gianni-rosato/vac-enc",children:"VAC"}),", or Value Added Codec, is a libopus encoder that uses SoX to resample inputs & supports output to ",(0,s.jsx)(n.code,{children:".ogg"})," rather than exclusively ",(0,s.jsx)(n.code,{children:".opus"}),". Better resampling theoretically leads to better coding efficiency, but vac-enc hasn't been thoroughly tested."]}),"\n",(0,s.jsxs)(n.p,{children:["Encoding a 16-bit signed little endian ",(0,s.jsx)(n.code,{children:"pcm_s16le"})," WAV to 128kbit/s Opus in an OGG container:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vac-enc input.wav output.ogg 128\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>r});var s=i(6540);const o={},t=s.createContext(o);function a(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[1554],{2120:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var s=i(4848),o=i(8453);const t={title:"Opus",sidebar_position:2},a="Opus",r={id:"audio/Opus",title:"Opus",description:"The content in this entry is incomplete & is in the process of being completed.",source:"@site/docs/audio/Opus.mdx",sourceDirName:"audio",slug:"/audio/Opus",permalink:"/docs/audio/Opus",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/audio/Opus.mdx",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Opus",sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"AAC",permalink:"/docs/audio/AAC"},next:{title:"Dolby Digital",permalink:"/docs/audio/Dolby"}},c={},d=[{value:"Format Breakdown",id:"format-breakdown",level:2},{value:"SILK",id:"silk",level:3},{value:"CELT",id:"celt",level:3},{value:"Encoders",id:"encoders",level:2},{value:"Opusenc",id:"opusenc",level:3},{value:"FFopus",id:"ffopus",level:3},{value:"vac-enc",id:"vac-enc",level:3}];function l(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",br:"br",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"opus",children:"Opus"}),"\n",(0,s.jsx)(n.admonition,{title:"Under Maintenance",type:"info",children:(0,s.jsx)(n.p,{children:"The content in this entry is incomplete & is in the process of being completed."})}),"\n",(0,s.jsxs)(n.p,{children:["Opus is an open-source audio codec that has largely replaced ",(0,s.jsx)(n.a,{href:"/docs/audio/Vorbis",children:"Vorbis"})," as the standard open audio codec. It is the recommended codec for usage in WebM video containers in tandem with the ",(0,s.jsx)(n.a,{href:"/docs/video/VP9",children:"VP9"})," or ",(0,s.jsx)(n.a,{href:"/docs/video/AV1",children:"AV1"})," video codecs."]}),"\n",(0,s.jsxs)(n.p,{children:["Opus is known for its incredible coding efficiency and unique multi-channel optimizations. Stereo Opus audio reaches ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Transparency_(data_compression)",children:"transparency"})," (psychoacoustically lossless audio quality) at 128kb/s, compared to ",(0,s.jsx)(n.a,{href:"/docs/audio/AAC",children:"AAC"}),"'s generally agreed upon 256kb/s and ",(0,s.jsx)(n.a,{href:"/docs/audio/MP3",children:"MP3"}),"'s 320kb/s. Transparency varies based on the type of content & the encoding implementation used, especially for codecs other than Opus, and the values provided above may be debated to a degree."]}),"\n",(0,s.jsxs)(n.p,{children:["Opus is described on ",(0,s.jsx)(n.a,{href:"https://opus-codec.org/",children:"opus-codec.org"}),' as a "totally open, royalty-free, highly versatile audio codec. Opus is unmatched for interactive speech and music transmission over the Internet, but is also intended for storage and streaming applications. It is standardized by the Internet Engineering Task Force (IETF) as ',(0,s.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc6716",children:"RFC 6716"}),' which incorporated technology from Skype\u2019s SILK codec and Xiph.Org\u2019s CELT codec."']}),"\n",(0,s.jsx)(n.p,{children:"Opus supports the following features:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Bitrates from 6 kb/s to 510 kb/s (with a maximum of around 255 kb/s per channel on non stereo layouts)"}),"\n",(0,s.jsx)(n.li,{children:"Sampling rates from 8 kHz (narrowband) to 48 kHz (fullband)"}),"\n",(0,s.jsx)(n.li,{children:"Frame sizes from 2.5 ms to 60 ms"}),"\n",(0,s.jsx)(n.li,{children:"Support for both constant bitrate (CBR) and variable bitrate (VBR)"}),"\n",(0,s.jsx)(n.li,{children:"Audio bandwidth from narrowband to fullband"}),"\n",(0,s.jsx)(n.li,{children:"Support for speech and music"}),"\n",(0,s.jsx)(n.li,{children:"Support for mono and stereo"}),"\n",(0,s.jsx)(n.li,{children:"Support for up to 255 channels (multistream frames)"}),"\n",(0,s.jsx)(n.li,{children:"Dynamically adjustable bitrate, audio bandwidth, and frame size"}),"\n",(0,s.jsx)(n.li,{children:"Good loss robustness and packet loss concealment (PLC)"}),"\n",(0,s.jsx)(n.li,{children:"Floating point and fixed-point implementation"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"via opus-codec.org and wiki.hydrogenaud.io"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"format-breakdown",children:"Format Breakdown"}),"\n",(0,s.jsx)(n.p,{children:"Opus is a hybrid audio codec, composed of two codecs as mentioned above. These are Skype's SILK codec for voice & Xiph.Org's CELT codec. Opus's initial name, Harmony, may have been because of the \"harmony\" of these two codecs and the musical connotation of harmony."}),"\n",(0,s.jsx)(n.h3,{id:"silk",children:"SILK"}),"\n",(0,s.jsx)(n.p,{children:"SILK, initially from Skype, was designed to be used for voice calls on Microsoft products like Skype. The first stable release of the codec was in 2009, and since then it has been freely licensed under the BSD 2-Clause license which has allowed for its adoption into Opus. The version of SILK used in Opus is substantially modified from - and not compatible with - the standalone SILK codec previously described here."}),"\n",(0,s.jsx)(n.p,{children:"SILK is optimized for speech, and so has limited sample rates as follows:"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Narrowband: 3-4000hz\nMediumband: 3-6000hz\nWideband: 3-8000hz"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"SILK's latency is 10 to 60ms based on the desired framesize + 5ms lookahead to estimate noise shaping + (potentially) 1.5ms sampling rate conversion overhead if the input audio needs to be resampled."}),"\n",(0,s.jsx)(n.h3,{id:"celt",children:"CELT"}),"\n",(0,s.jsx)(n.p,{children:'Much like SILK, CELT is under the BSD 2-Clause license. The preview release came out in 2011. CELT stands for "Code-Excited Lapped Transform" and was designed to be the true successor to Vorbis, even being dubbed as "Vorbis II" during its initial development as part og Xiph.Org\'s "Ghost" project in 2005.'}),"\n",(0,s.jsxs)(n.p,{children:["CELT was designed to be a full-band general purpose codec without a particular specialization for a certain kind of audio, making it distinctly different from Xiph's ",(0,s.jsx)(n.a,{href:"/docs/audio/Speex",children:"Speex"})," codec & more similar to Vorbis. It is computationally simple relative to competing codec technologies like ",(0,s.jsx)(n.a,{href:"/docs/audio/AAC",children:"AAC"})," & even Vorbis, enabling extremely low latency that is competitive with ",(0,s.jsx)(n.a,{href:"/docs/audio/AAC#aac-ld--aac-eld",children:"AAC-LD"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"CELT can work with the following sample rates:"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Narrowband: 3-4000hz\nMediumband: 3-6000hz\nWideband: 3-8000hz\nSuperWideband: 3-12000hz\nFullband: 3-20000hz"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"encoders",children:"Encoders"}),"\n",(0,s.jsx)(n.h3,{id:"opusenc",children:"Opusenc"}),"\n",(0,s.jsxs)(n.p,{children:["Opus's reference encoder is ",(0,s.jsx)(n.a,{href:"https://github.com/xiph/opus",children:"opusenc"}),", which is known for its fantastic performance and versatility. It is licensed under the BSD 3-clause license as part of the reference libopus library. There are a myriad of options that may be used to encode with opusenc, but the utility is considered to have sane encoding defaults for local storage & playback. The best options will be outlined below."]}),"\n",(0,s.jsxs)(n.p,{children:["Usage: ",(0,s.jsx)(n.code,{children:"opusenc [options] input_file output_file.opus"})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--bitrate #.###"})," Sets the overall target bitrate in kbit/s. Most encoders use ",(0,s.jsx)(n.em,{children:"bits"}),' per second, meaning you have to specify "128K" for 128kbit/s for example. Opus doesn\'t follow this, so you\'d just have to type "128" though keep in mind using efficient VBR encoding means the final bitrate may be different than the target. Opus supports bitrates from 6 kb/s to 510 kb/s.']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--vbr"})," Tells the encoder to encode using a variable bit rate, allocating more or less bits when necessary to preserve overall fidelity per bit. This is the best option for local storage & playback, and is ",(0,s.jsx)(n.em,{children:"enabled by default."})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--cvbr"})," Tells the encoder that it is allowed to vary the bitrate like with VBR, but it must constrain the maximum bitrate at any given moment to the value provided."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--hard-cbr"})," Tells the encoder to use a constant bitrate the whole time."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--music"})," & ",(0,s.jsx)(n.code,{children:"--speech"})," Forces the AI content-detector built into opusenc to treat the input as either speech or music. The bitrate range where this is relevant is around 12-40kb/s."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--comp #"})," Sets the encoder complexity to a value from 0 to 10, 0 being the least complex & 10 being the most. ",(0,s.jsx)(n.em,{children:"The default is 10."})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--framesize #"})," Sets the maximum encoder frame size in milliseconds. Lowering this is useful for improving latency at the expense of audio quality per bit. It is worth noting that 40 & 60ms framesizes are just multiple 20ms frames stitched together via opusenc's default behavior, and are not considered useful as they just lower the encoder's adaptability which can worsen both latency & coding efficiency. ",(0,s.jsx)(n.em,{children:"The default value is 20."})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--expect-loss #"})," Percentage value for expected packet loss. Not useful for local encoding & playback, but useful for real-time applications. ",(0,s.jsx)(n.em,{children:"Default value is 0."})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--downmix-mono"})," Downmixes multiple channels into a single channel."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--downmix-stereo"})," Downmixes multiple channels into two channels, left & right, given more than two channels are provided to the encoder."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--no-phase-inv"})," Disables phase inversion. Helpful when downmixing stereo to mono, although this is the default behavior in that scenario since libopus 1.3. Slightly decreases stereo audio quality."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"--max-delay #"})," Sets maximum container delay in milliseconds, from 0-1000. ",(0,s.jsx)(n.em,{children:"Default is 1000."})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Looking at the default values for the encoder flags, opusenc almost always follows the best practices for every default value. This makes it very easy to use, and it is as simple as plugging in a source of some kind and using only the most basic commands to encode with opus."}),"\n",(0,s.jsx)(n.p,{children:"An example opusenc command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'opusenc "input.wav" "output.opus" --bitrate 96\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/docs/utilities/ffmpeg",children:"FFmpeg"})," using libopus:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'ffmpeg -i "input.flac" -c:a libopus -b:a 128K "output.ogg"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you'd like to learn more about opusenc & its recommended default behavior, read this article on ",(0,s.jsx)(n.a,{href:"https://wiki.xiph.org/Opus_Recommended_Settings#Bandwidth_Transition_Thresholds",children:"Opus Recommended Settings"}),"."]}),"\n",(0,s.jsxs)(n.admonition,{title:"Existing bug in ffmpeg",type:"info",children:[(0,s.jsxs)(n.p,{children:["Due to a bug in ffmpeg ",(0,s.jsx)(n.a,{href:"https://trac.ffmpeg.org/ticket/5718",children:"(#5718)"}),", ffmpeg won't automatically remap ",(0,s.jsx)(n.code,{children:"5.1(side)"})," to ",(0,s.jsx)(n.code,{children:"5.1"})," when using libopus.",(0,s.jsx)(n.br,{}),"\n","To remap the channel layout explicitly, try this:"]}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'ffmpeg -i "input.flac" -c:a libopus -af aformat=channel_layouts=5.1 "output.ogg"\n'})}),(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsx)(n.p,{children:"You can handle arbitrary audio stream mappings with this:"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"-af aformat=channel_layouts=7.1|5.1|stereo -mapping_family 1\n"})})]})]}),"\n",(0,s.jsx)(n.h3,{id:"ffopus",children:"FFopus"}),"\n",(0,s.jsx)(n.p,{children:"FFopus is an experimental native opus encoder from FFmpeg. It is not widely regarded as providing any decent uplift in coding efficiency compared to libopus, and is usually considered worse; its only merit is being able to handle 5.1(side) streams while libopus in FFmpeg cannot. It only implements the CELT part of the Opus codec."}),"\n",(0,s.jsx)(n.p,{children:"FFopus usage:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'ffmpeg -i "input.wma" -c:a opus -b:a 128K -strict -2 "output.opus"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"vac-enc",children:"vac-enc"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/gianni-rosato/vac-enc",children:"VAC"}),", or Value Added Codec, is a libopus encoder that uses SoX to resample inputs & supports output to ",(0,s.jsx)(n.code,{children:".ogg"})," rather than exclusively ",(0,s.jsx)(n.code,{children:".opus"}),". Better resampling theoretically leads to better coding efficiency, but vac-enc hasn't been thoroughly tested."]}),"\n",(0,s.jsxs)(n.p,{children:["Encoding a 16-bit signed little endian ",(0,s.jsx)(n.code,{children:"pcm_s16le"})," WAV to 128kbit/s Opus in an OGG container:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vac-enc input.wav output.ogg 128\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>r});var s=i(6540);const o={},t=s.createContext(o);function a(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0b185270.72d28bf6.js b/assets/js/0b185270.72d28bf6.js new file mode 100644 index 000000000..2c75b78f1 --- /dev/null +++ b/assets/js/0b185270.72d28bf6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[3482],{5754:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var n=i(4848),o=i(8453);const s={title:"FAQ",sidebar_label:"\u2753 FAQ",position:14},r="FAQ",a={id:"FAQ",title:"FAQ",description:"Why are you doing this?",source:"@site/docs/FAQ.mdx",sourceDirName:".",slug:"/FAQ",permalink:"/docs/FAQ",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/FAQ.mdx",tags:[],version:"current",frontMatter:{title:"FAQ",sidebar_label:"\u2753 FAQ",position:14},sidebar:"tutorialSidebar",previous:{title:"\u2712\ufe0f Contribution Guide",permalink:"/docs/contribution-guide"},next:{title:"\ud83d\udd0f Privacy Policy",permalink:"/docs/privacy-policy"}},d={},c=[{value:"Why are you doing this?",id:"why-are-you-doing-this",level:2},{value:"But alternatives exist. Why not contribute there?",id:"but-alternatives-exist-why-not-contribute-there",level:3},{value:"How do I get started as a contributor?",id:"how-do-i-get-started-as-a-contributor",level:3},{value:"Why "Codec Wiki"?",id:"why-codec-wiki",level:3}];function l(e){const t={a:"a",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"faq",children:"FAQ"}),"\n",(0,n.jsx)(t.h2,{id:"why-are-you-doing-this",children:"Why are you doing this?"}),"\n",(0,n.jsx)(t.p,{children:"Multimedia encoding & the digital compression space is an incredible field that many tech enthusiasts, professionals, & laymen have no easy entry point to. Wikipedia has a vast amount of information on many of the individual topics covered here but doesn't offer a cohesive way to engage with the entire sphere of knowledge as a whole. While this site started as a lighthearted guide (you'll see the remnants of this strewn about the various wiki entries), it has quickly become an endeavor to unite digital compression aficionados to make the knowledge more accessible for all."}),"\n",(0,n.jsx)(t.h3,{id:"but-alternatives-exist-why-not-contribute-there",children:"But alternatives exist. Why not contribute there?"}),"\n",(0,n.jsx)(t.p,{children:"While this is true, this is easier said than done."}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Multimedia Wiki is not as active as it used to be, & a new effort makes sense to carry past efforts forward."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://guide.encode.moe/",children:"guide.encode.moe"})," is stagnant and mostly focused on fansub, docs & personal experiences that are scattered around the Internet."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"There are sources littered about that explain pieces of the larger puzzle, but these serve as small drops in a bucket of vast incoherency & don't meaningfully remedy the steep learning curve for understanding multimedia compression without background knowledge."}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"how-do-i-get-started-as-a-contributor",children:"How do I get started as a contributor?"}),"\n",(0,n.jsx)(t.p,{children:"See our Contribution Guide page in the sidebar."}),"\n",(0,n.jsx)(t.h3,{id:"why-codec-wiki",children:'Why "Codec Wiki"?'}),"\n",(0,n.jsx)(t.p,{children:'This wiki is mostly going to be focused on multimedia compression, & the term "Codec" is already widely recognized & understood. While other topics like video filtering & general compression algorithms may be covered, the main focus remains multimedia compression.'})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},8453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>a});var n=i(6540);const o={},s=n.createContext(o);function r(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0b185270.d29f97f0.js b/assets/js/0b185270.d29f97f0.js deleted file mode 100644 index cf9d41d90..000000000 --- a/assets/js/0b185270.d29f97f0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[3482],{455:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var n=i(4848),o=i(8453);const s={title:"FAQ",sidebar_label:"\u2753 FAQ",position:14},r="FAQ",a={id:"FAQ",title:"FAQ",description:"Why are you doing this?",source:"@site/docs/FAQ.mdx",sourceDirName:".",slug:"/FAQ",permalink:"/docs/FAQ",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/FAQ.mdx",tags:[],version:"current",frontMatter:{title:"FAQ",sidebar_label:"\u2753 FAQ",position:14},sidebar:"tutorialSidebar",previous:{title:"\u2712\ufe0f Contribution Guide",permalink:"/docs/contribution-guide"},next:{title:"\ud83d\udd0f Privacy Policy",permalink:"/docs/privacy-policy"}},d={},c=[{value:"Why are you doing this?",id:"why-are-you-doing-this",level:2},{value:"But alternatives exist. Why not contribute there?",id:"but-alternatives-exist-why-not-contribute-there",level:3},{value:"How do I get started as a contributor?",id:"how-do-i-get-started-as-a-contributor",level:3},{value:"Why "Codec Wiki"?",id:"why-codec-wiki",level:3}];function l(e){const t={a:"a",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"faq",children:"FAQ"}),"\n",(0,n.jsx)(t.h2,{id:"why-are-you-doing-this",children:"Why are you doing this?"}),"\n",(0,n.jsx)(t.p,{children:"Multimedia encoding & the digital compression space is an incredible field that many tech enthusiasts, professionals, & laymen have no easy entry point to. Wikipedia has a vast amount of information on many of the individual topics covered here but doesn't offer a cohesive way to engage with the entire sphere of knowledge as a whole. While this site started as a lighthearted guide (you'll see the remnants of this strewn about the various wiki entries), it has quickly become an endeavor to unite digital compression aficionados to make the knowledge more accessible for all."}),"\n",(0,n.jsx)(t.h3,{id:"but-alternatives-exist-why-not-contribute-there",children:"But alternatives exist. Why not contribute there?"}),"\n",(0,n.jsx)(t.p,{children:"While this is true, this is easier said than done."}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Multimedia Wiki is not as active as it used to be, & a new effort makes sense to carry past efforts forward."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://guide.encode.moe/",children:"guide.encode.moe"})," is stagnant and mostly focused on fansub, docs & personal experiences that are scattered around the Internet."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"There are sources littered about that explain pieces of the larger puzzle, but these serve as small drops in a bucket of vast incoherency & don't meaningfully remedy the steep learning curve for understanding multimedia compression without background knowledge."}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"how-do-i-get-started-as-a-contributor",children:"How do I get started as a contributor?"}),"\n",(0,n.jsx)(t.p,{children:"See our Contribution Guide page in the sidebar."}),"\n",(0,n.jsx)(t.h3,{id:"why-codec-wiki",children:'Why "Codec Wiki"?'}),"\n",(0,n.jsx)(t.p,{children:'This wiki is mostly going to be focused on multimedia compression, & the term "Codec" is already widely recognized & understood. While other topics like video filtering & general compression algorithms may be covered, the main focus remains multimedia compression.'})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},8453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>a});var n=i(6540);const o={},s=n.createContext(o);function r(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0c06159a.40ea409d.js b/assets/js/0c06159a.b875faf9.js similarity index 98% rename from assets/js/0c06159a.40ea409d.js rename to assets/js/0c06159a.b875faf9.js index 5e46c73c0..0b3990b51 100644 --- a/assets/js/0c06159a.40ea409d.js +++ b/assets/js/0c06159a.b875faf9.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[8258],{1339:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>n,metadata:()=>s,toc:()=>d});var i=a(4848),r=a(8453);const n={title:"tar",sidebar_position:8},o="tar",s={id:"data/tar",title:"tar",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/data/tar.mdx",sourceDirName:"data",slug:"/data/tar",permalink:"/docs/data/tar",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/data/tar.mdx",tags:[],version:"current",sidebarPosition:8,frontMatter:{title:"tar",sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"zstd",permalink:"/docs/data/zstd"},next:{title:"JPEG",permalink:"/docs/images/JPEG"}},c={},d=[{value:"Usage",id:"usage",level:2},{value:"Create a tar archive",id:"create-a-tar-archive",level:3},{value:"Extract a tar archive",id:"extract-a-tar-archive",level:3}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"tar",children:"tar"}),"\n",(0,i.jsx)(t.admonition,{title:"Help Wanted",type:"danger",children:(0,i.jsxs)(t.p,{children:["This section is in need of contributions. If you believe you can help, please see our ",(0,i.jsx)(t.a,{href:"/docs/contribution-guide",children:"Contribution Guide"})," to get started as a contributor!"]})}),"\n",(0,i.jsx)(t.p,{children:'tar, or Tape ARchive, is a archiving format and utility first developed for Version 7 Unix in 1977. It\'s original purpose was to collate files into one that can be stored on tape. Similarly, today it is used to bring many files together into a "tarball", which can be compressed with any general data compression algorithm.'}),"\n",(0,i.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(t.admonition,{type:"note",children:(0,i.jsx)(t.p,{children:"This guide has been written for GNU tar on linux, however it should be applicable to BSD tar, macOS tar, and the tar command in powershell on Windows."})}),"\n",(0,i.jsx)(t.h3,{id:"create-a-tar-archive",children:"Create a tar archive"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"tar -cf {archive name} {files listed here}\n"})}),"\n",(0,i.jsxs)(t.p,{children:["You can use ",(0,i.jsx)(t.code,{children:"tar"})," to compress your archive, for example into a ",(0,i.jsx)(t.code,{children:".tar.gz"})," or ",(0,i.jsx)(t.code,{children:".tar.xz"})," archive. To do this, you either can either use a flag such as ",(0,i.jsx)(t.code,{children:"-z"}),", ",(0,i.jsx)(t.code,{children:"-j"}),", or ",(0,i.jsx)(t.code,{children:"-J"})," (",(0,i.jsx)(t.a,{href:"/docs/data/gzip",children:"gzip"}),", ",(0,i.jsx)(t.a,{href:"/docs/data/bzip2",children:"bzip2"}),", ",(0,i.jsx)(t.a,{href:"/docs/data/xz",children:"xz"}),"), or you can use ",(0,i.jsx)(t.code,{children:"-a"})," ('automatic'), which allows it to intuit what algorithm you want from the file extension, such as ",(0,i.jsx)(t.code,{children:"archive.tar.xz"})," for an xz compressed tarball."]}),"\n",(0,i.jsx)(t.p,{children:"GNU tar can use these compression algorithms"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"gzip (.gz)"}),"\n",(0,i.jsx)(t.li,{children:"bzip2 (.bz)"}),"\n",(0,i.jsx)(t.li,{children:"xz (.xz)"}),"\n",(0,i.jsx)(t.li,{children:"lzip (.lz)"}),"\n",(0,i.jsx)(t.li,{children:"lzma (.lzma)"}),"\n",(0,i.jsx)(t.li,{children:"lzop (.lzo)"}),"\n",(0,i.jsx)(t.li,{children:"zstd (.zstd)"}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"extract-a-tar-archive",children:"Extract a tar archive"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"tar -xf {tarball}.tar -C {directory to extract to}\n"})}),"\n",(0,i.jsxs)(t.p,{children:["tar can extract from it's supported compressed formats, such as ",(0,i.jsx)(t.code,{children:"archive.tar.xz"})," automatically, with no extra flags."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,t,a)=>{a.d(t,{R:()=>o,x:()=>s});var i=a(6540);const r={},n=i.createContext(r);function o(e){const t=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[8258],{5420:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>n,metadata:()=>s,toc:()=>d});var i=a(4848),r=a(8453);const n={title:"tar",sidebar_position:8},o="tar",s={id:"data/tar",title:"tar",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/data/tar.mdx",sourceDirName:"data",slug:"/data/tar",permalink:"/docs/data/tar",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/data/tar.mdx",tags:[],version:"current",sidebarPosition:8,frontMatter:{title:"tar",sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"zstd",permalink:"/docs/data/zstd"},next:{title:"JPEG",permalink:"/docs/images/JPEG"}},c={},d=[{value:"Usage",id:"usage",level:2},{value:"Create a tar archive",id:"create-a-tar-archive",level:3},{value:"Extract a tar archive",id:"extract-a-tar-archive",level:3}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"tar",children:"tar"}),"\n",(0,i.jsx)(t.admonition,{title:"Help Wanted",type:"danger",children:(0,i.jsxs)(t.p,{children:["This section is in need of contributions. If you believe you can help, please see our ",(0,i.jsx)(t.a,{href:"/docs/contribution-guide",children:"Contribution Guide"})," to get started as a contributor!"]})}),"\n",(0,i.jsx)(t.p,{children:'tar, or Tape ARchive, is a archiving format and utility first developed for Version 7 Unix in 1977. It\'s original purpose was to collate files into one that can be stored on tape. Similarly, today it is used to bring many files together into a "tarball", which can be compressed with any general data compression algorithm.'}),"\n",(0,i.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(t.admonition,{type:"note",children:(0,i.jsx)(t.p,{children:"This guide has been written for GNU tar on linux, however it should be applicable to BSD tar, macOS tar, and the tar command in powershell on Windows."})}),"\n",(0,i.jsx)(t.h3,{id:"create-a-tar-archive",children:"Create a tar archive"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"tar -cf {archive name} {files listed here}\n"})}),"\n",(0,i.jsxs)(t.p,{children:["You can use ",(0,i.jsx)(t.code,{children:"tar"})," to compress your archive, for example into a ",(0,i.jsx)(t.code,{children:".tar.gz"})," or ",(0,i.jsx)(t.code,{children:".tar.xz"})," archive. To do this, you either can either use a flag such as ",(0,i.jsx)(t.code,{children:"-z"}),", ",(0,i.jsx)(t.code,{children:"-j"}),", or ",(0,i.jsx)(t.code,{children:"-J"})," (",(0,i.jsx)(t.a,{href:"/docs/data/gzip",children:"gzip"}),", ",(0,i.jsx)(t.a,{href:"/docs/data/bzip2",children:"bzip2"}),", ",(0,i.jsx)(t.a,{href:"/docs/data/xz",children:"xz"}),"), or you can use ",(0,i.jsx)(t.code,{children:"-a"})," ('automatic'), which allows it to intuit what algorithm you want from the file extension, such as ",(0,i.jsx)(t.code,{children:"archive.tar.xz"})," for an xz compressed tarball."]}),"\n",(0,i.jsx)(t.p,{children:"GNU tar can use these compression algorithms"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"gzip (.gz)"}),"\n",(0,i.jsx)(t.li,{children:"bzip2 (.bz)"}),"\n",(0,i.jsx)(t.li,{children:"xz (.xz)"}),"\n",(0,i.jsx)(t.li,{children:"lzip (.lz)"}),"\n",(0,i.jsx)(t.li,{children:"lzma (.lzma)"}),"\n",(0,i.jsx)(t.li,{children:"lzop (.lzo)"}),"\n",(0,i.jsx)(t.li,{children:"zstd (.zstd)"}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"extract-a-tar-archive",children:"Extract a tar archive"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"tar -xf {tarball}.tar -C {directory to extract to}\n"})}),"\n",(0,i.jsxs)(t.p,{children:["tar can extract from it's supported compressed formats, such as ",(0,i.jsx)(t.code,{children:"archive.tar.xz"})," automatically, with no extra flags."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,t,a)=>{a.d(t,{R:()=>o,x:()=>s});var i=a(6540);const r={},n=i.createContext(r);function o(e){const t=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0e7f53a8.5bb74cf6.js b/assets/js/0e7f53a8.a7772943.js similarity index 97% rename from assets/js/0e7f53a8.5bb74cf6.js rename to assets/js/0e7f53a8.a7772943.js index e5b1d748c..5e1dbbb07 100644 --- a/assets/js/0e7f53a8.5bb74cf6.js +++ b/assets/js/0e7f53a8.a7772943.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[9954],{929:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var s=n(4848),t=n(8453);const r={title:"PNG",sidebar_position:2},o="PNG",c={id:"images/PNG",title:"PNG",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/images/PNG.mdx",sourceDirName:"images",slug:"/images/PNG",permalink:"/docs/images/PNG",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/images/PNG.mdx",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"PNG",sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"JPEG",permalink:"/docs/images/JPEG"},next:{title:"GIF",permalink:"/docs/images/GIF"}},a={},d=[{value:"Performance Checklist",id:"performance-checklist",level:2}];function l(e){const i={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",p:"p",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h1,{id:"png",children:"PNG"}),"\n",(0,s.jsx)(i.admonition,{title:"Help Wanted",type:"danger",children:(0,s.jsxs)(i.p,{children:["This section is in need of contributions. If you believe you can help, please see our ",(0,s.jsx)(i.a,{href:"/docs/contribution-guide",children:"Contribution Guide"})," to get started as a contributor!"]})}),"\n",(0,s.jsxs)(i.p,{children:["Portable Network Graphics (PNG) is a free lossless image file format released in 1996. It was ceated as an alternative to ",(0,s.jsx)(i.a,{href:"/docs/images/GIF",children:"GIF"}),", which was at the time a proprietary format. It gained animation support similar to GIF with the release of APNG in 2008, which is now supported by all popular web browsers."]}),"\n",(0,s.jsx)(i.h2,{id:"performance-checklist",children:"Performance Checklist"}),"\n",(0,s.jsxs)(i.p,{children:["Lossless? ",(0,s.jsx)(i.em,{children:"Yes"})]}),"\n",(0,s.jsxs)(i.p,{children:["Lossy? ",(0,s.jsx)(i.em,{children:"No"})]}),"\n",(0,s.jsxs)(i.p,{children:["Supported Bit Depths:\n",(0,s.jsx)(i.em,{children:"8 BPC, 16 BPC"})]}),"\n",(0,s.jsxs)(i.p,{children:["HDR/Wide Gamut? ",(0,s.jsx)(i.em,{children:"Yes"})]}),"\n",(0,s.jsxs)(i.p,{children:["Animation? ",(0,s.jsx)(i.em,{children:"Yes"})]}),"\n",(0,s.jsxs)(i.p,{children:["Transparency? ",(0,s.jsx)(i.em,{children:"Yes"})]}),"\n",(0,s.jsxs)(i.p,{children:["Progressive Decode? ",(0,s.jsx)(i.em,{children:"Kinda"})]}),"\n",(0,s.jsxs)(i.p,{children:["Royalty Free? ",(0,s.jsx)(i.em,{children:"Yes"})]})]})}function h(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>o,x:()=>c});var s=n(6540);const t={},r=s.createContext(t);function o(e){const i=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[9954],{970:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var s=n(4848),t=n(8453);const r={title:"PNG",sidebar_position:2},o="PNG",c={id:"images/PNG",title:"PNG",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/images/PNG.mdx",sourceDirName:"images",slug:"/images/PNG",permalink:"/docs/images/PNG",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/images/PNG.mdx",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"PNG",sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"JPEG",permalink:"/docs/images/JPEG"},next:{title:"GIF",permalink:"/docs/images/GIF"}},a={},d=[{value:"Performance Checklist",id:"performance-checklist",level:2}];function l(e){const i={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",p:"p",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h1,{id:"png",children:"PNG"}),"\n",(0,s.jsx)(i.admonition,{title:"Help Wanted",type:"danger",children:(0,s.jsxs)(i.p,{children:["This section is in need of contributions. If you believe you can help, please see our ",(0,s.jsx)(i.a,{href:"/docs/contribution-guide",children:"Contribution Guide"})," to get started as a contributor!"]})}),"\n",(0,s.jsxs)(i.p,{children:["Portable Network Graphics (PNG) is a free lossless image file format released in 1996. It was ceated as an alternative to ",(0,s.jsx)(i.a,{href:"/docs/images/GIF",children:"GIF"}),", which was at the time a proprietary format. It gained animation support similar to GIF with the release of APNG in 2008, which is now supported by all popular web browsers."]}),"\n",(0,s.jsx)(i.h2,{id:"performance-checklist",children:"Performance Checklist"}),"\n",(0,s.jsxs)(i.p,{children:["Lossless? ",(0,s.jsx)(i.em,{children:"Yes"})]}),"\n",(0,s.jsxs)(i.p,{children:["Lossy? ",(0,s.jsx)(i.em,{children:"No"})]}),"\n",(0,s.jsxs)(i.p,{children:["Supported Bit Depths:\n",(0,s.jsx)(i.em,{children:"8 BPC, 16 BPC"})]}),"\n",(0,s.jsxs)(i.p,{children:["HDR/Wide Gamut? ",(0,s.jsx)(i.em,{children:"Yes"})]}),"\n",(0,s.jsxs)(i.p,{children:["Animation? ",(0,s.jsx)(i.em,{children:"Yes"})]}),"\n",(0,s.jsxs)(i.p,{children:["Transparency? ",(0,s.jsx)(i.em,{children:"Yes"})]}),"\n",(0,s.jsxs)(i.p,{children:["Progressive Decode? ",(0,s.jsx)(i.em,{children:"Kinda"})]}),"\n",(0,s.jsxs)(i.p,{children:["Royalty Free? ",(0,s.jsx)(i.em,{children:"Yes"})]})]})}function h(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>o,x:()=>c});var s=n(6540);const t={},r=s.createContext(t);function o(e){const i=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/112763a5.1530487f.js b/assets/js/112763a5.2f24865d.js similarity index 99% rename from assets/js/112763a5.1530487f.js rename to assets/js/112763a5.2f24865d.js index 73edbe6ef..e6ad5e8be 100644 --- a/assets/js/112763a5.1530487f.js +++ b/assets/js/112763a5.2f24865d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[1779],{5836:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var i=o(4848),n=o(8453);const s={title:"Terms of Use",sidebar_label:"\ud83e\udd1d Terms of Use",position:16},r="Terms of Use",a={id:"terms-of-use",title:"Terms of Use",description:"These terms & conditions outline the rules & regulations for the use of the Codec Wiki Website as a visitor, contributor, or any other party who falls under the jurisdiction of these terms.",source:"@site/docs/terms-of-use.mdx",sourceDirName:".",slug:"/terms-of-use",permalink:"/docs/terms-of-use",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/terms-of-use.mdx",tags:[],version:"current",frontMatter:{title:"Terms of Use",sidebar_label:"\ud83e\udd1d Terms of Use",position:16},sidebar:"tutorialSidebar",previous:{title:"\ud83d\udd0f Privacy Policy",permalink:"/docs/privacy-policy"}},l={},c=[];function h(e){const t={a:"a",blockquote:"blockquote",h1:"h1",li:"li",ol:"ol",p:"p",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"terms-of-use",children:"Terms of Use"}),"\n",(0,i.jsx)(t.p,{children:"These terms & conditions outline the rules & regulations for the use of the Codec Wiki Website as a visitor, contributor, or any other party who falls under the jurisdiction of these terms."}),"\n",(0,i.jsx)(t.p,{children:"By accessing this website we assume you accept these terms & conditions. Do not continue to use the site if you do not agree to all of the terms & conditions stated on this page."}),"\n",(0,i.jsx)(t.p,{children:"The following terminology applies to these Terms & Conditions & all other Agreements: \u201cClient\u201d, \u201cYou\u201d & \u201cYour\u201d refers to you, the person log on this website & compliant to these terms & conditions. \u201cOurselves\u201d, \u201cWe\u201d, \u201cOur\u201d & \u201cUs\u201d, refers to the site's owner. \u201cParty\u201d, \u201cParties\u201d, or \u201cUs\u201d, refers to both the Client & ourselves. Any use of the above terminology or other words in the singular, plural, capitalization and/or they/he/she, are taken as interchangeable & therefore as referring to the same."}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Cookies"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"We may employ the use of cookies in the future. At the time of writing, we do not. If accessing the site employs the use of cookies, you will be prompted to agree to use cookies in agreement with our Privacy Policy. As of writing, our Privacy Policy does not require users' consent to the use of cookies due to the fact that we do not use cookies."}),"\n",(0,i.jsx)(t.p,{children:"Some interactive websites use cookies to let them retrieve user details for each visit. Cookies may be used by our website to enable the functionality of certain areas to make it easier for people visiting our website."}),"\n",(0,i.jsxs)(t.ol,{start:"2",children:["\n",(0,i.jsx)(t.li,{children:"Licensing"}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["Unless otherwise stated, the site's contributors and/or its licensors own the intellectual property rights for all material on the Codec Wiki. All intellectual property is distributed under CC BY-SA 4.0 unless it is specified otherwise. You may assess the terms & conditions of this Creative Commons license via this link: ",(0,i.jsx)(t.a,{href:"https://creativecommons.org/licenses/by-sa/4.0/",children:"https://creativecommons.org/licenses/by-sa/4.0/"}),". Using assets and/or intellectual property from the Codec Wiki site is subject to these terms unless otherwise specified."]}),"\n",(0,i.jsx)(t.p,{children:"Under CC BY-SA 4.0, you may:"}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:"Share - copy and redistribute the material in any medium or format."}),"\n"]}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:"Adapt - remix, transform, and build upon the material for any purpose, even commercially."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"No party can revoke these freedoms as long as you follow the license terms. The terms are as follows:"}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:"Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use."}),"\n"]}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:"ShareAlike - If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Contributors may not apply legal terms or technological measures that legally restrict others from doing anything the license permits."}),"\n",(0,i.jsx)(t.p,{children:"Parts of this website may offer an opportunity for users to post & exchange opinions & information in certain areas of the site. We do not filter, edit, publish or review Comments prior to their presence on the website. Comments do not reflect the views & opinions of contributors, its agents and/or affiliates. Comments reflect the views & opinions of the person who posts their views & opinions. To the extent permitted by applicable laws, the site's host & wiki contributors shall not be liable for the Comments or any liability, damages or expenses caused and/or suffered as a result of any use of and/or posting of and/or appearance of the Comments on this website."}),"\n",(0,i.jsx)(t.p,{children:"Part of the nature of a community-developed wiki is the ability for members of the community to make contributions to the contents of the site. Contributors are responsible for their own contributions to the site, & we shall not be liable for the contributions or any liability, damages or expenses caused and/or suffered as a result of any use of and/or posting of and/or appearance of the contributions to this website."}),"\n",(0,i.jsx)(t.p,{children:"We reserve the right to monitor all Comments and/or contributions & to remove any Comments and/or contributions which can be considered inappropriate, offensive or causes a breach of these Terms & Conditions."}),"\n",(0,i.jsx)(t.p,{children:"You warrant & represent that:"}),"\n",(0,i.jsx)(t.p,{children:"You are entitled to post the Comments/contributions on our website & have all necessary licenses & consents to do so;\nThe Comments/contributions do not invade any intellectual property right, including without limitation copyright, patent or trademark of any third party;\nThe Comments/contributions do not contain any defamatory, libelous, offensive, indecent or otherwise unlawful material which is an invasion of privacy\nThe Comments/contributions will not be used to promote unlawful activity."}),"\n",(0,i.jsx)(t.p,{children:"You hereby grant the Codec Wiki a non-exclusive license to use, reproduce, edit & authorize others to use, reproduce & edit any of your Comments/contributions in any & all forms, formats or media."}),"\n",(0,i.jsxs)(t.ol,{start:"3",children:["\n",(0,i.jsx)(t.li,{children:"iFrames"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"You may not create frames around our Webpages that alter in any way the visual presentation or appearance of our Website without proper attribution per CC BY-SA 4.0 where the license applies. Elsewhere, written permission is required if an asset is not under the CC BY-SA 4.0 license."}),"\n",(0,i.jsxs)(t.ol,{start:"4",children:["\n",(0,i.jsx)(t.li,{children:"Content Liability"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"We shall not be held responsible for any content that appears on your Website. You agree to protect & defend us against all claims that arise on your Website. No link(s) should appear on any Website that may be interpreted as libelous, obscene, or criminal, or which infringes, otherwise violates, or advocates the infringement or other violation of, any third party rights."}),"\n",(0,i.jsxs)(t.ol,{start:"5",children:["\n",(0,i.jsx)(t.li,{children:"Your Privacy"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Please read our Privacy Policy."}),"\n",(0,i.jsxs)(t.ol,{start:"6",children:["\n",(0,i.jsx)(t.li,{children:"Reservation of Rights"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"We reserve the right to request that you remove all links or any particular link to our Website. You approve to immediately remove all links to our Website upon request. We also reserve the right to amend these terms & conditions & its linking policy at any time. By continuously linking to our Website, you agree to be bound to & follow these terms & conditions."}),"\n",(0,i.jsxs)(t.ol,{start:"7",children:["\n",(0,i.jsx)(t.li,{children:"Removal of links from our website"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"If you find any link on our Website that is offensive for any reason, you are free to contact & inform us at any moment. We will consider requests to remove links but we are not obligated to or so or to respond to you directly. We do not ensure that the information on this website is correct, we do not warrant its completeness or accuracy; nor do we promise to ensure that the website remains available or that the material on the website is kept up-to-date."}),"\n",(0,i.jsxs)(t.ol,{start:"8",children:["\n",(0,i.jsx)(t.li,{children:"Disclaimer"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"To the maximum extent permitted by applicable law, we exclude all representations, warranties & conditions relating to our website & the use of this website. Nothing in this disclaimer will:"}),"\n",(0,i.jsx)(t.p,{children:"limit or exclude our or your liability for death or personal injury;\nlimit or exclude our or your liability for fraud or fraudulent misrepresentation;\nlimit any of our or your liabilities in any way that is not permitted under applicable law; or\nexclude any of our or your liabilities that may not be excluded under applicable law."}),"\n",(0,i.jsx)(t.p,{children:"The limitations & prohibitions of liability set in this Section & elsewhere in this disclaimer: (a) are subject to the preceding paragraph; & (b) govern all liabilities arising under the disclaimer, including liabilities arising in contract, in tort & for breach of statutory duty."}),"\n",(0,i.jsx)(t.p,{children:"As long as the website & the information on the website are provided free of charge, we will not be liable for any loss or damage of any nature."})]})}function u(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},8453:(e,t,o)=>{o.d(t,{R:()=>r,x:()=>a});var i=o(6540);const n={},s=i.createContext(n);function r(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[1779],{9503:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var i=o(4848),n=o(8453);const s={title:"Terms of Use",sidebar_label:"\ud83e\udd1d Terms of Use",position:16},r="Terms of Use",a={id:"terms-of-use",title:"Terms of Use",description:"These terms & conditions outline the rules & regulations for the use of the Codec Wiki Website as a visitor, contributor, or any other party who falls under the jurisdiction of these terms.",source:"@site/docs/terms-of-use.mdx",sourceDirName:".",slug:"/terms-of-use",permalink:"/docs/terms-of-use",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/terms-of-use.mdx",tags:[],version:"current",frontMatter:{title:"Terms of Use",sidebar_label:"\ud83e\udd1d Terms of Use",position:16},sidebar:"tutorialSidebar",previous:{title:"\ud83d\udd0f Privacy Policy",permalink:"/docs/privacy-policy"}},l={},c=[];function h(e){const t={a:"a",blockquote:"blockquote",h1:"h1",li:"li",ol:"ol",p:"p",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"terms-of-use",children:"Terms of Use"}),"\n",(0,i.jsx)(t.p,{children:"These terms & conditions outline the rules & regulations for the use of the Codec Wiki Website as a visitor, contributor, or any other party who falls under the jurisdiction of these terms."}),"\n",(0,i.jsx)(t.p,{children:"By accessing this website we assume you accept these terms & conditions. Do not continue to use the site if you do not agree to all of the terms & conditions stated on this page."}),"\n",(0,i.jsx)(t.p,{children:"The following terminology applies to these Terms & Conditions & all other Agreements: \u201cClient\u201d, \u201cYou\u201d & \u201cYour\u201d refers to you, the person log on this website & compliant to these terms & conditions. \u201cOurselves\u201d, \u201cWe\u201d, \u201cOur\u201d & \u201cUs\u201d, refers to the site's owner. \u201cParty\u201d, \u201cParties\u201d, or \u201cUs\u201d, refers to both the Client & ourselves. Any use of the above terminology or other words in the singular, plural, capitalization and/or they/he/she, are taken as interchangeable & therefore as referring to the same."}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Cookies"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"We may employ the use of cookies in the future. At the time of writing, we do not. If accessing the site employs the use of cookies, you will be prompted to agree to use cookies in agreement with our Privacy Policy. As of writing, our Privacy Policy does not require users' consent to the use of cookies due to the fact that we do not use cookies."}),"\n",(0,i.jsx)(t.p,{children:"Some interactive websites use cookies to let them retrieve user details for each visit. Cookies may be used by our website to enable the functionality of certain areas to make it easier for people visiting our website."}),"\n",(0,i.jsxs)(t.ol,{start:"2",children:["\n",(0,i.jsx)(t.li,{children:"Licensing"}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["Unless otherwise stated, the site's contributors and/or its licensors own the intellectual property rights for all material on the Codec Wiki. All intellectual property is distributed under CC BY-SA 4.0 unless it is specified otherwise. You may assess the terms & conditions of this Creative Commons license via this link: ",(0,i.jsx)(t.a,{href:"https://creativecommons.org/licenses/by-sa/4.0/",children:"https://creativecommons.org/licenses/by-sa/4.0/"}),". Using assets and/or intellectual property from the Codec Wiki site is subject to these terms unless otherwise specified."]}),"\n",(0,i.jsx)(t.p,{children:"Under CC BY-SA 4.0, you may:"}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:"Share - copy and redistribute the material in any medium or format."}),"\n"]}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:"Adapt - remix, transform, and build upon the material for any purpose, even commercially."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"No party can revoke these freedoms as long as you follow the license terms. The terms are as follows:"}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:"Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use."}),"\n"]}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:"ShareAlike - If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Contributors may not apply legal terms or technological measures that legally restrict others from doing anything the license permits."}),"\n",(0,i.jsx)(t.p,{children:"Parts of this website may offer an opportunity for users to post & exchange opinions & information in certain areas of the site. We do not filter, edit, publish or review Comments prior to their presence on the website. Comments do not reflect the views & opinions of contributors, its agents and/or affiliates. Comments reflect the views & opinions of the person who posts their views & opinions. To the extent permitted by applicable laws, the site's host & wiki contributors shall not be liable for the Comments or any liability, damages or expenses caused and/or suffered as a result of any use of and/or posting of and/or appearance of the Comments on this website."}),"\n",(0,i.jsx)(t.p,{children:"Part of the nature of a community-developed wiki is the ability for members of the community to make contributions to the contents of the site. Contributors are responsible for their own contributions to the site, & we shall not be liable for the contributions or any liability, damages or expenses caused and/or suffered as a result of any use of and/or posting of and/or appearance of the contributions to this website."}),"\n",(0,i.jsx)(t.p,{children:"We reserve the right to monitor all Comments and/or contributions & to remove any Comments and/or contributions which can be considered inappropriate, offensive or causes a breach of these Terms & Conditions."}),"\n",(0,i.jsx)(t.p,{children:"You warrant & represent that:"}),"\n",(0,i.jsx)(t.p,{children:"You are entitled to post the Comments/contributions on our website & have all necessary licenses & consents to do so;\nThe Comments/contributions do not invade any intellectual property right, including without limitation copyright, patent or trademark of any third party;\nThe Comments/contributions do not contain any defamatory, libelous, offensive, indecent or otherwise unlawful material which is an invasion of privacy\nThe Comments/contributions will not be used to promote unlawful activity."}),"\n",(0,i.jsx)(t.p,{children:"You hereby grant the Codec Wiki a non-exclusive license to use, reproduce, edit & authorize others to use, reproduce & edit any of your Comments/contributions in any & all forms, formats or media."}),"\n",(0,i.jsxs)(t.ol,{start:"3",children:["\n",(0,i.jsx)(t.li,{children:"iFrames"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"You may not create frames around our Webpages that alter in any way the visual presentation or appearance of our Website without proper attribution per CC BY-SA 4.0 where the license applies. Elsewhere, written permission is required if an asset is not under the CC BY-SA 4.0 license."}),"\n",(0,i.jsxs)(t.ol,{start:"4",children:["\n",(0,i.jsx)(t.li,{children:"Content Liability"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"We shall not be held responsible for any content that appears on your Website. You agree to protect & defend us against all claims that arise on your Website. No link(s) should appear on any Website that may be interpreted as libelous, obscene, or criminal, or which infringes, otherwise violates, or advocates the infringement or other violation of, any third party rights."}),"\n",(0,i.jsxs)(t.ol,{start:"5",children:["\n",(0,i.jsx)(t.li,{children:"Your Privacy"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Please read our Privacy Policy."}),"\n",(0,i.jsxs)(t.ol,{start:"6",children:["\n",(0,i.jsx)(t.li,{children:"Reservation of Rights"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"We reserve the right to request that you remove all links or any particular link to our Website. You approve to immediately remove all links to our Website upon request. We also reserve the right to amend these terms & conditions & its linking policy at any time. By continuously linking to our Website, you agree to be bound to & follow these terms & conditions."}),"\n",(0,i.jsxs)(t.ol,{start:"7",children:["\n",(0,i.jsx)(t.li,{children:"Removal of links from our website"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"If you find any link on our Website that is offensive for any reason, you are free to contact & inform us at any moment. We will consider requests to remove links but we are not obligated to or so or to respond to you directly. We do not ensure that the information on this website is correct, we do not warrant its completeness or accuracy; nor do we promise to ensure that the website remains available or that the material on the website is kept up-to-date."}),"\n",(0,i.jsxs)(t.ol,{start:"8",children:["\n",(0,i.jsx)(t.li,{children:"Disclaimer"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"To the maximum extent permitted by applicable law, we exclude all representations, warranties & conditions relating to our website & the use of this website. Nothing in this disclaimer will:"}),"\n",(0,i.jsx)(t.p,{children:"limit or exclude our or your liability for death or personal injury;\nlimit or exclude our or your liability for fraud or fraudulent misrepresentation;\nlimit any of our or your liabilities in any way that is not permitted under applicable law; or\nexclude any of our or your liabilities that may not be excluded under applicable law."}),"\n",(0,i.jsx)(t.p,{children:"The limitations & prohibitions of liability set in this Section & elsewhere in this disclaimer: (a) are subject to the preceding paragraph; & (b) govern all liabilities arising under the disclaimer, including liabilities arising in contract, in tort & for breach of statutory duty."}),"\n",(0,i.jsx)(t.p,{children:"As long as the website & the information on the website are provided free of charge, we will not be liable for any loss or damage of any nature."})]})}function u(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},8453:(e,t,o)=>{o.d(t,{R:()=>r,x:()=>a});var i=o(6540);const n={},s=i.createContext(n);function r(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/66935117.703b8d17.js b/assets/js/121fdfc4.1aeeb7b3.js similarity index 84% rename from assets/js/66935117.703b8d17.js rename to assets/js/121fdfc4.1aeeb7b3.js index 635a9476b..1e1c6a321 100644 --- a/assets/js/66935117.703b8d17.js +++ b/assets/js/121fdfc4.1aeeb7b3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[2017],{5585:a=>{a.exports=JSON.parse('{"tag":{"label":"anniversary","permalink":"/blog/tags/anniversary","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/anniversary","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[8304],{9342:a=>{a.exports=JSON.parse('{"tag":{"label":"anniversary","permalink":"/blog/tags/anniversary","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/anniversary","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/12b076f3.71cdfb3a.js b/assets/js/12b076f3.2f2479ae.js similarity index 99% rename from assets/js/12b076f3.71cdfb3a.js rename to assets/js/12b076f3.2f2479ae.js index dc318c7f6..ad4496d75 100644 --- a/assets/js/12b076f3.71cdfb3a.js +++ b/assets/js/12b076f3.2f2479ae.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[7222],{9905:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>d,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>n,toc:()=>l});var i=t(4848),o=t(8453);const a={title:"zstd",sidebar_position:7},r="Zstandard",n={id:"data/zstd",title:"zstd",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/data/zstd.mdx",sourceDirName:"data",slug:"/data/zstd",permalink:"/docs/data/zstd",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/data/zstd.mdx",tags:[],version:"current",sidebarPosition:7,frontMatter:{title:"zstd",sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"zpaq",permalink:"/docs/data/zpaq"},next:{title:"tar",permalink:"/docs/data/tar"}},d={},l=[{value:"Usage",id:"usage",level:2},{value:"Compress a file",id:"compress-a-file",level:2},{value:"Decompress a file",id:"decompress-a-file",level:2}];function c(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h1,{id:"zstandard",children:"Zstandard"}),"\n",(0,i.jsx)(s.admonition,{title:"Help Wanted",type:"danger",children:(0,i.jsxs)(s.p,{children:["This section is in need of contributions. If you believe you can help, please see our ",(0,i.jsx)(s.a,{href:"/docs/contribution-guide",children:"Contribution Guide"})," to get started as a contributor!"]})}),"\n",(0,i.jsxs)(s.p,{children:["Zstandard is a compression algorithm developed by Facebook known for its extremely fast decompression speeds. It was released in early 2015 and is used in a variety of different contexts. It was designed to perform similarly to older Deflate-based compression algorithms like ",(0,i.jsx)(s.a,{href:"/docs/data/zip",children:"ZIP"})," or ",(0,i.jsx)(s.a,{href:"/docs/data/gzip",children:"gzip"})," while being faster overall. In practice, it is said to compress similarly to pure LZMA (part of ",(0,i.jsx)(s.a,{href:"/docs/data/xz",children:"XZ"})," & ",(0,i.jsx)(s.a,{href:"/docs/data/7z",children:"7-zip"}),") while being much faster."]}),"\n",(0,i.jsxs)(s.p,{children:["While ",(0,i.jsx)(s.code,{children:".tar.zstd"})," archives aren't as popular as ",(0,i.jsx)(s.code,{children:".tar.xz"})," or ",(0,i.jsx)(s.code,{children:".tar.gz"}),", Zstandard is already a very popular tool for compression in the world of open-source software. It has been integrated into both the FreeBSD kernel & the Linux kernel and is available as a filesystem compression method for the btrfs, squashfs, bcachefs, & OpenZFS filesystems. Filesystem compression refers to a compression scheme that transparently compresses files stored on a filesystem at all times, leading to an overall reduction in storage used across the filesystem."]}),"\n",(0,i.jsxs)(s.p,{children:["The command line ",(0,i.jsx)(s.code,{children:"zstd"})," utility can compress to Zstandard at compression levels 1 through 19 by default. The upper bound is raised to 22 when passing the ",(0,i.jsx)(s.code,{children:"--ultra"})," flag. All Arch Linux packages are compressed at zstd level 20, allowing Arch packages to be decompressed 14 times faster compared to XZ at the cost of an average 0.8% filesize increase across all packages. It is popular in the game emulation scene as well, as many game file formats for emulating console games support zstd compression. The ZIP file format standard actually supports Zstandard in compression level 93 since version 6.3.8, published in 2020. Content encoding using zstd is supported in chromium since Chromium 118 behind an experimental flag, meaning it might compete with ",(0,i.jsx)(s.a,{href:"/docs/data/brotli",children:"Brotli"})," on the web in the future. Apple's LZFSE algorithm is purportedly similar to Zstandard compression level 6."]}),"\n",(0,i.jsxs)(s.p,{children:["Zstandard has the potential to effectively compete with nearly every modern compression method available across most modern use cases. In certain scenarios, if it takes off as a content delivery format, it could replace Brotli if the benefits of super-fast & super-light decode improve the responsiveness of web pages & are worth sacrificing a bit of compression ratio. When using the much higher effort settings, it often outcompetes Brotli for the archive size as well. In the future, ",(0,i.jsx)(s.code,{children:".tar.zst"})," could replace 7-zip, ZIP, or other archiving formats, making speedy decode a reality on systems featuring varying levels of compute horsepower."]}),"\n",(0,i.jsx)(s.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(s.admonition,{type:"note",children:(0,i.jsxs)(s.p,{children:["This guide has been written for the ",(0,i.jsx)(s.code,{children:"zstd"})," command-line utility, however GUI archivers such as peazip and 7zip have growing support for zstd."]})}),"\n",(0,i.jsx)(s.h2,{id:"compress-a-file",children:"Compress a file"}),"\n",(0,i.jsxs)(s.p,{children:["Like many other compressing utilities, in order to compress mutliple files, one should probably archive them with ",(0,i.jsx)(s.a,{href:"/docs/data/tar",children:"tar"}),"."]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-bash",children:"zstd -# {file} -o {file}.zstd\n"})}),"\n",(0,i.jsxs)(s.p,{children:[(0,i.jsx)(s.code,{children:"-#"})," is actually a number that represents the desired compression level, for example ",(0,i.jsx)(s.code,{children:"-3"}),", ",(0,i.jsx)(s.code,{children:"-6"}),". By default you can specify 1-19. By also passing ",(0,i.jsx)(s.code,{children:"-ultra"}),", you can go up to compression level 22."]}),"\n",(0,i.jsx)(s.h2,{id:"decompress-a-file",children:"Decompress a file"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-bash",children:"zstd -d {file}.zstd -o file\n"})})]})}function p(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>n});var i=t(6540);const o={},a=i.createContext(o);function r(e){const s=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function n(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[7222],{5340:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>d,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>n,toc:()=>l});var i=t(4848),o=t(8453);const a={title:"zstd",sidebar_position:7},r="Zstandard",n={id:"data/zstd",title:"zstd",description:"This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor!",source:"@site/docs/data/zstd.mdx",sourceDirName:"data",slug:"/data/zstd",permalink:"/docs/data/zstd",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/data/zstd.mdx",tags:[],version:"current",sidebarPosition:7,frontMatter:{title:"zstd",sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"zpaq",permalink:"/docs/data/zpaq"},next:{title:"tar",permalink:"/docs/data/tar"}},d={},l=[{value:"Usage",id:"usage",level:2},{value:"Compress a file",id:"compress-a-file",level:2},{value:"Decompress a file",id:"decompress-a-file",level:2}];function c(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h1,{id:"zstandard",children:"Zstandard"}),"\n",(0,i.jsx)(s.admonition,{title:"Help Wanted",type:"danger",children:(0,i.jsxs)(s.p,{children:["This section is in need of contributions. If you believe you can help, please see our ",(0,i.jsx)(s.a,{href:"/docs/contribution-guide",children:"Contribution Guide"})," to get started as a contributor!"]})}),"\n",(0,i.jsxs)(s.p,{children:["Zstandard is a compression algorithm developed by Facebook known for its extremely fast decompression speeds. It was released in early 2015 and is used in a variety of different contexts. It was designed to perform similarly to older Deflate-based compression algorithms like ",(0,i.jsx)(s.a,{href:"/docs/data/zip",children:"ZIP"})," or ",(0,i.jsx)(s.a,{href:"/docs/data/gzip",children:"gzip"})," while being faster overall. In practice, it is said to compress similarly to pure LZMA (part of ",(0,i.jsx)(s.a,{href:"/docs/data/xz",children:"XZ"})," & ",(0,i.jsx)(s.a,{href:"/docs/data/7z",children:"7-zip"}),") while being much faster."]}),"\n",(0,i.jsxs)(s.p,{children:["While ",(0,i.jsx)(s.code,{children:".tar.zstd"})," archives aren't as popular as ",(0,i.jsx)(s.code,{children:".tar.xz"})," or ",(0,i.jsx)(s.code,{children:".tar.gz"}),", Zstandard is already a very popular tool for compression in the world of open-source software. It has been integrated into both the FreeBSD kernel & the Linux kernel and is available as a filesystem compression method for the btrfs, squashfs, bcachefs, & OpenZFS filesystems. Filesystem compression refers to a compression scheme that transparently compresses files stored on a filesystem at all times, leading to an overall reduction in storage used across the filesystem."]}),"\n",(0,i.jsxs)(s.p,{children:["The command line ",(0,i.jsx)(s.code,{children:"zstd"})," utility can compress to Zstandard at compression levels 1 through 19 by default. The upper bound is raised to 22 when passing the ",(0,i.jsx)(s.code,{children:"--ultra"})," flag. All Arch Linux packages are compressed at zstd level 20, allowing Arch packages to be decompressed 14 times faster compared to XZ at the cost of an average 0.8% filesize increase across all packages. It is popular in the game emulation scene as well, as many game file formats for emulating console games support zstd compression. The ZIP file format standard actually supports Zstandard in compression level 93 since version 6.3.8, published in 2020. Content encoding using zstd is supported in chromium since Chromium 118 behind an experimental flag, meaning it might compete with ",(0,i.jsx)(s.a,{href:"/docs/data/brotli",children:"Brotli"})," on the web in the future. Apple's LZFSE algorithm is purportedly similar to Zstandard compression level 6."]}),"\n",(0,i.jsxs)(s.p,{children:["Zstandard has the potential to effectively compete with nearly every modern compression method available across most modern use cases. In certain scenarios, if it takes off as a content delivery format, it could replace Brotli if the benefits of super-fast & super-light decode improve the responsiveness of web pages & are worth sacrificing a bit of compression ratio. When using the much higher effort settings, it often outcompetes Brotli for the archive size as well. In the future, ",(0,i.jsx)(s.code,{children:".tar.zst"})," could replace 7-zip, ZIP, or other archiving formats, making speedy decode a reality on systems featuring varying levels of compute horsepower."]}),"\n",(0,i.jsx)(s.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(s.admonition,{type:"note",children:(0,i.jsxs)(s.p,{children:["This guide has been written for the ",(0,i.jsx)(s.code,{children:"zstd"})," command-line utility, however GUI archivers such as peazip and 7zip have growing support for zstd."]})}),"\n",(0,i.jsx)(s.h2,{id:"compress-a-file",children:"Compress a file"}),"\n",(0,i.jsxs)(s.p,{children:["Like many other compressing utilities, in order to compress mutliple files, one should probably archive them with ",(0,i.jsx)(s.a,{href:"/docs/data/tar",children:"tar"}),"."]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-bash",children:"zstd -# {file} -o {file}.zstd\n"})}),"\n",(0,i.jsxs)(s.p,{children:[(0,i.jsx)(s.code,{children:"-#"})," is actually a number that represents the desired compression level, for example ",(0,i.jsx)(s.code,{children:"-3"}),", ",(0,i.jsx)(s.code,{children:"-6"}),". By default you can specify 1-19. By also passing ",(0,i.jsx)(s.code,{children:"-ultra"}),", you can go up to compression level 22."]}),"\n",(0,i.jsx)(s.h2,{id:"decompress-a-file",children:"Decompress a file"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-bash",children:"zstd -d {file}.zstd -o file\n"})})]})}function p(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>n});var i=t(6540);const o={},a=i.createContext(o);function r(e){const s=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function n(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/12df3b9e.94d39739.js b/assets/js/12df3b9e.b189bdce.js similarity index 99% rename from assets/js/12df3b9e.94d39739.js rename to assets/js/12df3b9e.b189bdce.js index 08f2be0a7..18e105db5 100644 --- a/assets/js/12df3b9e.94d39739.js +++ b/assets/js/12df3b9e.b189bdce.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[9993],{1793:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var i=s(4848),t=s(8453);const r={title:"QOI",sidebar_position:8},o="QOI",a={id:"images/QOI",title:"QOI",description:"QOI (Quite OK Image Format) is an image compression format that aims to provide a simple, fast, and efficient way to compress and decompress images losslessly. It was designed to be easy to implement while offering better compression ratios than the widely used but more complex PNG format while achieving much faster encoding & decoding speeds.",source:"@site/docs/images/QOI.mdx",sourceDirName:"images",slug:"/images/QOI",permalink:"/docs/images/QOI",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/images/QOI.mdx",tags:[],version:"current",sidebarPosition:8,frontMatter:{title:"QOI",sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"JPEG-XL",permalink:"/docs/images/JXL"},next:{title:"x264",permalink:"/docs/encoders/x264"}},l={},d=[{value:"Performance Checklist",id:"performance-checklist",level:2},{value:"Format Breakdown",id:"format-breakdown",level:2},{value:"Benchmarks",id:"benchmarks",level:3},{value:"Advantages",id:"advantages",level:3},{value:"Limitations",id:"limitations",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"qoi",children:"QOI"}),"\n",(0,i.jsxs)(n.p,{children:["QOI (Quite OK Image Format) is an image compression format that aims to provide a simple, fast, and efficient way to compress and decompress images losslessly. It was designed to be easy to implement while offering better compression ratios than the widely used but more complex ",(0,i.jsx)(n.a,{href:"/docs/images/PNG",children:"PNG"})," format while achieving much faster encoding & decoding speeds."]}),"\n",(0,i.jsx)(n.h2,{id:"performance-checklist",children:"Performance Checklist"}),"\n",(0,i.jsxs)(n.p,{children:["Lossless? ",(0,i.jsx)(n.em,{children:"Yes"})]}),"\n",(0,i.jsxs)(n.p,{children:["Lossy? ",(0,i.jsx)(n.em,{children:"No"})]}),"\n",(0,i.jsxs)(n.p,{children:["Supported Bit Depths:\n",(0,i.jsx)(n.em,{children:"8 BPC"})]}),"\n",(0,i.jsxs)(n.p,{children:["HDR/Wide Gamut? ",(0,i.jsx)(n.em,{children:"No"})]}),"\n",(0,i.jsxs)(n.p,{children:["Animation? ",(0,i.jsx)(n.em,{children:"No"})]}),"\n",(0,i.jsxs)(n.p,{children:["Transparency? ",(0,i.jsx)(n.em,{children:"Yes"})]}),"\n",(0,i.jsxs)(n.p,{children:["Progressive Decode? ",(0,i.jsx)(n.em,{children:"No"})]}),"\n",(0,i.jsxs)(n.p,{children:["Royalty Free? ",(0,i.jsx)(n.em,{children:"Yes"})]}),"\n",(0,i.jsx)(n.h2,{id:"format-breakdown",children:"Format Breakdown"}),"\n",(0,i.jsx)(n.p,{children:"QOI compression is based on a simple and fast algorithm that exploits spatial redundancy in images. The algorithm uses a combination of run-length encoding (RLE), a small lookup table, delta encoding, and full-color pixel storage to achieve efficient compression. Depending on the algorithm's decision, a chunk (pixel) can take up one to five bytes."}),"\n",(0,i.jsx)(n.p,{children:"The QOI format supports images with 3 or 4 channels (RGB or RGBA) and 8 bits per channel. The format supports two colorspaces: Linear RGB & sRGB with linear alpha. These do not affect the way pixels are encoded."}),"\n",(0,i.jsx)(n.p,{children:"Here is a breakdown of the various chunk types in QOI:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_RGB"})}),": Full RGB pixel value using 8 bits (1 byte) for each of the red, green, and blue channels. The alpha channel is 255 in RGB images, and always remains unchanged."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_RGBA"})}),": Full RGBA pixel value using 8 bits for each of the red, green, blue, & alpha channels."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_DIFF"})}),": The difference between the current pixel and the previous pixel for the red, green, and blue channels are stored using 2 bits for each channel. The differences are stored with a bias of 2 and wrap (so 1 minus 2 would be 255). The alpha channel remains unchanged."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_LUMA"})}),": These pixels encode the green channel difference from the previous pixel using 6 bits, and then encode the red and blue channel differences relative to the green channel difference using 4 bits each. This allows for more efficient encoding of small color changes. The alpha channel remains unchanged."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_RUN"})}),": These are the simplest, encoding a run-length of pixels that are identical to the previous pixel. The run length is stored using 6 bits with a bias of -1, allowing for runs of 1 to 62 pixels."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_INDEX"})}),": These are stored by referencing a previously seen pixel value from a rolling array of 64 recent pixel values by using a simple hash on each pixel as it is identified. If another pixel matches a previously seen hash value in the array, the index of the referenced pixel is stored."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The QOI format also includes a simple 14-byte header that stores the image dimensions, color space, and channel depth information. The end of file is signaled by an 8-byte end marker."}),"\n",(0,i.jsx)(n.h3,{id:"benchmarks",children:"Benchmarks"}),"\n",(0,i.jsxs)(n.p,{children:["The creator of QOI benchmarked the format against libpng & ",(0,i.jsx)(n.code,{children:"stbi_image_write"})," using the C implementation in QOI via ",(0,i.jsx)(n.a,{href:"https://github.com/phoboslab/qoi/blob/master/qoibench.c",children:(0,i.jsx)(n.code,{children:"qoibench.c"})})," on a collection of 2,879 screenshots, icons, photos, & textures (",(0,i.jsx)(n.a,{href:"https://qoiformat.org/benchmark/qoi_benchmark_suite.tar",children:"source"}),"). The results are as follows:"]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Library"})}),(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Decode (ms)"})}),(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Encode (ms)"})}),(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Decode MP/s"})}),(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Encode MP/s"})}),(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Size (kb)"})}),(0,i.jsx)(n.th,{style:{textAlign:"right"},children:(0,i.jsx)(n.strong,{children:"Compression Rate"})})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"libpng"})}),(0,i.jsx)(n.td,{children:"7.0"}),(0,i.jsx)(n.td,{children:"83.8"}),(0,i.jsx)(n.td,{children:"66.56"}),(0,i.jsx)(n.td,{children:"5.54"}),(0,i.jsx)(n.td,{children:"398"}),(0,i.jsx)(n.td,{style:{textAlign:"right"},children:"24.2%"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"stbi"})}),(0,i.jsx)(n.td,{children:"7.0"}),(0,i.jsx)(n.td,{children:"60.5"}),(0,i.jsx)(n.td,{children:"66.63"}),(0,i.jsx)(n.td,{children:"7.67"}),(0,i.jsx)(n.td,{children:"561"}),(0,i.jsx)(n.td,{style:{textAlign:"right"},children:"34.2%"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"qoi"})}),(0,i.jsx)(n.td,{children:"2.1"}),(0,i.jsx)(n.td,{children:"2.9"}),(0,i.jsx)(n.td,{children:"226.03"}),(0,i.jsx)(n.td,{children:"161.99"}),(0,i.jsx)(n.td,{children:"463"}),(0,i.jsx)(n.td,{style:{textAlign:"right"},children:"28.2%"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["The results show that QOI is significantly faster than libpng and ",(0,i.jsx)(n.code,{children:"stb_image_write"}),", and it also achieves better compression ratios than libpng on average."]}),"\n",(0,i.jsx)(n.h3,{id:"advantages",children:"Advantages"}),"\n",(0,i.jsx)(n.p,{children:"Some of the key advantages of QOI include:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Super simple: ",(0,i.jsx)(n.a,{href:"https://qoiformat.org/qoi-specification.pdf",children:"the spec"})," is only one page"]}),"\n",(0,i.jsx)(n.li,{children:"Extremely fast encoding & decoding speeds"}),"\n",(0,i.jsx)(n.li,{children:"Data chunks are byte-aligned, so data can be streamed to a decoder one byte at a time"}),"\n",(0,i.jsx)(n.li,{children:"Better compression ratios compared to PNG for many types of images"}),"\n",(0,i.jsx)(n.li,{children:"Supports transparency"}),"\n",(0,i.jsx)(n.li,{children:"Royalty-free, open-source (CC0), & easy to integrate into any application"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"limitations",children:"Limitations"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Limited to 8 bits per channel (no support for higher bit depths)"}),"\n",(0,i.jsx)(n.li,{children:"Not suitable for images with high-frequency noise or very little spatial redundancy"}),"\n",(0,i.jsx)(n.li,{children:"Lacks advanced features like progressive loading, interlacing, or custom metadata"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Despite its limitations, QOI provides a compelling alternative to PNG for many use cases where simplicity, speed, and good compression ratios are desired. QOI is not especially well supported at present, but adoption is rapidly growing as developers can easily integrate support into their applications due to the format's simplicity."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var i=s(6540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[9993],{4154:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var i=s(4848),t=s(8453);const r={title:"QOI",sidebar_position:8},o="QOI",a={id:"images/QOI",title:"QOI",description:"QOI (Quite OK Image Format) is an image compression format that aims to provide a simple, fast, and efficient way to compress and decompress images losslessly. It was designed to be easy to implement while offering better compression ratios than the widely used but more complex PNG format while achieving much faster encoding & decoding speeds.",source:"@site/docs/images/QOI.mdx",sourceDirName:"images",slug:"/images/QOI",permalink:"/docs/images/QOI",draft:!1,unlisted:!1,editUrl:"https://github.com/av1-community-contributors/codec-wiki/tree/main/docs/images/QOI.mdx",tags:[],version:"current",sidebarPosition:8,frontMatter:{title:"QOI",sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"JPEG-XL",permalink:"/docs/images/JXL"},next:{title:"x264",permalink:"/docs/encoders/x264"}},l={},d=[{value:"Performance Checklist",id:"performance-checklist",level:2},{value:"Format Breakdown",id:"format-breakdown",level:2},{value:"Benchmarks",id:"benchmarks",level:3},{value:"Advantages",id:"advantages",level:3},{value:"Limitations",id:"limitations",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"qoi",children:"QOI"}),"\n",(0,i.jsxs)(n.p,{children:["QOI (Quite OK Image Format) is an image compression format that aims to provide a simple, fast, and efficient way to compress and decompress images losslessly. It was designed to be easy to implement while offering better compression ratios than the widely used but more complex ",(0,i.jsx)(n.a,{href:"/docs/images/PNG",children:"PNG"})," format while achieving much faster encoding & decoding speeds."]}),"\n",(0,i.jsx)(n.h2,{id:"performance-checklist",children:"Performance Checklist"}),"\n",(0,i.jsxs)(n.p,{children:["Lossless? ",(0,i.jsx)(n.em,{children:"Yes"})]}),"\n",(0,i.jsxs)(n.p,{children:["Lossy? ",(0,i.jsx)(n.em,{children:"No"})]}),"\n",(0,i.jsxs)(n.p,{children:["Supported Bit Depths:\n",(0,i.jsx)(n.em,{children:"8 BPC"})]}),"\n",(0,i.jsxs)(n.p,{children:["HDR/Wide Gamut? ",(0,i.jsx)(n.em,{children:"No"})]}),"\n",(0,i.jsxs)(n.p,{children:["Animation? ",(0,i.jsx)(n.em,{children:"No"})]}),"\n",(0,i.jsxs)(n.p,{children:["Transparency? ",(0,i.jsx)(n.em,{children:"Yes"})]}),"\n",(0,i.jsxs)(n.p,{children:["Progressive Decode? ",(0,i.jsx)(n.em,{children:"No"})]}),"\n",(0,i.jsxs)(n.p,{children:["Royalty Free? ",(0,i.jsx)(n.em,{children:"Yes"})]}),"\n",(0,i.jsx)(n.h2,{id:"format-breakdown",children:"Format Breakdown"}),"\n",(0,i.jsx)(n.p,{children:"QOI compression is based on a simple and fast algorithm that exploits spatial redundancy in images. The algorithm uses a combination of run-length encoding (RLE), a small lookup table, delta encoding, and full-color pixel storage to achieve efficient compression. Depending on the algorithm's decision, a chunk (pixel) can take up one to five bytes."}),"\n",(0,i.jsx)(n.p,{children:"The QOI format supports images with 3 or 4 channels (RGB or RGBA) and 8 bits per channel. The format supports two colorspaces: Linear RGB & sRGB with linear alpha. These do not affect the way pixels are encoded."}),"\n",(0,i.jsx)(n.p,{children:"Here is a breakdown of the various chunk types in QOI:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_RGB"})}),": Full RGB pixel value using 8 bits (1 byte) for each of the red, green, and blue channels. The alpha channel is 255 in RGB images, and always remains unchanged."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_RGBA"})}),": Full RGBA pixel value using 8 bits for each of the red, green, blue, & alpha channels."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_DIFF"})}),": The difference between the current pixel and the previous pixel for the red, green, and blue channels are stored using 2 bits for each channel. The differences are stored with a bias of 2 and wrap (so 1 minus 2 would be 255). The alpha channel remains unchanged."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_LUMA"})}),": These pixels encode the green channel difference from the previous pixel using 6 bits, and then encode the red and blue channel differences relative to the green channel difference using 4 bits each. This allows for more efficient encoding of small color changes. The alpha channel remains unchanged."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_RUN"})}),": These are the simplest, encoding a run-length of pixels that are identical to the previous pixel. The run length is stored using 6 bits with a bias of -1, allowing for runs of 1 to 62 pixels."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"QOI_OP_INDEX"})}),": These are stored by referencing a previously seen pixel value from a rolling array of 64 recent pixel values by using a simple hash on each pixel as it is identified. If another pixel matches a previously seen hash value in the array, the index of the referenced pixel is stored."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The QOI format also includes a simple 14-byte header that stores the image dimensions, color space, and channel depth information. The end of file is signaled by an 8-byte end marker."}),"\n",(0,i.jsx)(n.h3,{id:"benchmarks",children:"Benchmarks"}),"\n",(0,i.jsxs)(n.p,{children:["The creator of QOI benchmarked the format against libpng & ",(0,i.jsx)(n.code,{children:"stbi_image_write"})," using the C implementation in QOI via ",(0,i.jsx)(n.a,{href:"https://github.com/phoboslab/qoi/blob/master/qoibench.c",children:(0,i.jsx)(n.code,{children:"qoibench.c"})})," on a collection of 2,879 screenshots, icons, photos, & textures (",(0,i.jsx)(n.a,{href:"https://qoiformat.org/benchmark/qoi_benchmark_suite.tar",children:"source"}),"). The results are as follows:"]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Library"})}),(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Decode (ms)"})}),(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Encode (ms)"})}),(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Decode MP/s"})}),(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Encode MP/s"})}),(0,i.jsx)(n.th,{children:(0,i.jsx)(n.strong,{children:"Size (kb)"})}),(0,i.jsx)(n.th,{style:{textAlign:"right"},children:(0,i.jsx)(n.strong,{children:"Compression Rate"})})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"libpng"})}),(0,i.jsx)(n.td,{children:"7.0"}),(0,i.jsx)(n.td,{children:"83.8"}),(0,i.jsx)(n.td,{children:"66.56"}),(0,i.jsx)(n.td,{children:"5.54"}),(0,i.jsx)(n.td,{children:"398"}),(0,i.jsx)(n.td,{style:{textAlign:"right"},children:"24.2%"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"stbi"})}),(0,i.jsx)(n.td,{children:"7.0"}),(0,i.jsx)(n.td,{children:"60.5"}),(0,i.jsx)(n.td,{children:"66.63"}),(0,i.jsx)(n.td,{children:"7.67"}),(0,i.jsx)(n.td,{children:"561"}),(0,i.jsx)(n.td,{style:{textAlign:"right"},children:"34.2%"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"qoi"})}),(0,i.jsx)(n.td,{children:"2.1"}),(0,i.jsx)(n.td,{children:"2.9"}),(0,i.jsx)(n.td,{children:"226.03"}),(0,i.jsx)(n.td,{children:"161.99"}),(0,i.jsx)(n.td,{children:"463"}),(0,i.jsx)(n.td,{style:{textAlign:"right"},children:"28.2%"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["The results show that QOI is significantly faster than libpng and ",(0,i.jsx)(n.code,{children:"stb_image_write"}),", and it also achieves better compression ratios than libpng on average."]}),"\n",(0,i.jsx)(n.h3,{id:"advantages",children:"Advantages"}),"\n",(0,i.jsx)(n.p,{children:"Some of the key advantages of QOI include:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Super simple: ",(0,i.jsx)(n.a,{href:"https://qoiformat.org/qoi-specification.pdf",children:"the spec"})," is only one page"]}),"\n",(0,i.jsx)(n.li,{children:"Extremely fast encoding & decoding speeds"}),"\n",(0,i.jsx)(n.li,{children:"Data chunks are byte-aligned, so data can be streamed to a decoder one byte at a time"}),"\n",(0,i.jsx)(n.li,{children:"Better compression ratios compared to PNG for many types of images"}),"\n",(0,i.jsx)(n.li,{children:"Supports transparency"}),"\n",(0,i.jsx)(n.li,{children:"Royalty-free, open-source (CC0), & easy to integrate into any application"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"limitations",children:"Limitations"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Limited to 8 bits per channel (no support for higher bit depths)"}),"\n",(0,i.jsx)(n.li,{children:"Not suitable for images with high-frequency noise or very little spatial redundancy"}),"\n",(0,i.jsx)(n.li,{children:"Lacks advanced features like progressive loading, interlacing, or custom metadata"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Despite its limitations, QOI provides a compelling alternative to PNG for many use cases where simplicity, speed, and good compression ratios are desired. QOI is not especially well supported at present, but adoption is rapidly growing as developers can easily integrate support into their applications due to the format's simplicity."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var i=s(6540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/17896441.4b4f5843.js b/assets/js/17896441.4b4f5843.js deleted file mode 100644 index 2f6cc9dd3..000000000 --- a/assets/js/17896441.4b4f5843.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodec_wiki=self.webpackChunkcodec_wiki||[]).push([[8401],{2447:(e,n,t)=>{t.r(n),t.d(n,{default:()=>ae});var s=t(6540),a=t(1213),i=t(9532),l=t(4848);const o=s.createContext(null);function r(e){let{children:n,content:t}=e;const a=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(t);return(0,l.jsx)(o.Provider,{value:a,children:n})}function c(){const e=(0,s.useContext)(o);if(null===e)throw new i.dV("DocProvider");return e}function d(){const{metadata:e,frontMatter:n,assets:t}=c();return(0,l.jsx)(a.be,{title:e.title,description:e.description,keywords:n.keywords,image:t.image??n.image})}var u=t(4164),m=t(4581),h=t(1312),v=t(9022);function b(e){const{previous:n,next:t}=e;return(0,l.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,h.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[n&&(0,l.jsx)(v.A,{...n,subLabel:(0,l.jsx)(h.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),t&&(0,l.jsx)(v.A,{...t,subLabel:(0,l.jsx)(h.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}function x(){const{metadata:e}=c();return(0,l.jsx)(b,{previous:e.previous,next:e.next})}var g=t(4586),p=t(8774),f=t(4070),j=t(7559),A=t(5597),C=t(2252);const L={unreleased:function(e){let{siteTitle:n,versionMetadata:t}=e;return(0,l.jsx)(h.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:n,versionLabel:(0,l.jsx)("b",{children:t.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:n,versionMetadata:t}=e;return(0,l.jsx)(h.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:n,versionLabel:(0,l.jsx)("b",{children:t.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function N(e){const n=L[e.versionMetadata.banner];return(0,l.jsx)(n,{...e})}function _(e){let{versionLabel:n,to:t,onClick:s}=e;return(0,l.jsx)(h.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:n,latestVersionLink:(0,l.jsx)("b",{children:(0,l.jsx)(p.A,{to:t,onClick:s,children:(0,l.jsx)(h.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function k(e){let{className:n,versionMetadata:t}=e;const{siteConfig:{title:s}}=(0,g.A)(),{pluginId:a}=(0,f.vT)({failfast:!0}),{savePreferredVersionName:i}=(0,A.g1)(a),{latestDocSuggestion:o,latestVersionSuggestion:r}=(0,f.HW)(a),c=o??(d=r).docs.find((e=>e.id===d.mainDocId));var d;return(0,l.jsxs)("div",{className:(0,u.A)(n,j.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,l.jsx)("div",{children:(0,l.jsx)(N,{siteTitle:s,versionMetadata:t})}),(0,l.jsx)("div",{className:"margin-top--md",children:(0,l.jsx)(_,{versionLabel:r.label,to:c.path,onClick:()=>i(r.name)})})]})}function T(e){let{className:n}=e;const t=(0,C.r)();return t.banner?(0,l.jsx)(k,{className:n,versionMetadata:t}):null}function H(e){let{className:n}=e;const t=(0,C.r)();return t.badge?(0,l.jsx)("span",{className:(0,u.A)(n,j.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,l.jsx)(h.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:t.label},children:"Version: {versionLabel}"})}):null}var M=t(2053),w=t(4336);function y(){const{metadata:e}=c(),{editUrl:n,lastUpdatedAt:t,lastUpdatedBy:s,tags:a}=e,i=a.length>0,o=!!(n||t||s);return i||o?(0,l.jsxs)("footer",{className:(0,u.A)(j.G.docs.docFooter,"docusaurus-mt-lg"),children:[i&&(0,l.jsx)("div",{className:(0,u.A)("row margin-top--sm",j.G.docs.docFooterTagsRow),children:(0,l.jsx)("div",{className:"col",children:(0,l.jsx)(M.A,{tags:a})})}),o&&(0,l.jsx)(w.A,{className:(0,u.A)("margin-top--sm",j.G.docs.docFooterEditMetaRow),editUrl:n,lastUpdatedAt:t,lastUpdatedBy:s})]}):null}var I=t(1422),E=t(5195);const B={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function O(e){let{collapsed:n,...t}=e;return(0,l.jsx)("button",{type:"button",...t,className:(0,u.A)("clean-btn",B.tocCollapsibleButton,!n&&B.tocCollapsibleButtonExpanded,t.className),children:(0,l.jsx)(h.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const V={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function G(e){let{toc:n,className:t,minHeadingLevel:s,maxHeadingLevel:a}=e;const{collapsed:i,toggleCollapsed:o}=(0,I.u)({initialState:!0});return(0,l.jsxs)("div",{className:(0,u.A)(V.tocCollapsible,!i&&V.tocCollapsibleExpanded,t),children:[(0,l.jsx)(O,{collapsed:i,onClick:o}),(0,l.jsx)(I.N,{lazy:!0,className:V.tocCollapsibleContent,collapsed:i,children:(0,l.jsx)(E.A,{toc:n,minHeadingLevel:s,maxHeadingLevel:a})})]})}const R={tocMobile:"tocMobile_ITEo"};function S(){const{toc:e,frontMatter:n}=c();return(0,l.jsx)(G,{toc:e,minHeadingLevel:n.toc_min_heading_level,maxHeadingLevel:n.toc_max_heading_level,className:(0,u.A)(j.G.docs.docTocMobile,R.tocMobile)})}var P=t(7763);function F(){const{toc:e,frontMatter:n}=c();return(0,l.jsx)(P.A,{toc:e,minHeadingLevel:n.toc_min_heading_level,maxHeadingLevel:n.toc_max_heading_level,className:j.G.docs.docTocDesktop})}var U=t(1107),D=t(8509);function z(e){let{children:n}=e;const t=function(){const{metadata:e,frontMatter:n,contentTitle:t}=c();return n.hide_title||void 0!==t?null:e.title}();return(0,l.jsxs)("div",{className:(0,u.A)(j.G.docs.docMarkdown,"markdown"),children:[t&&(0,l.jsx)("header",{children:(0,l.jsx)(U.A,{as:"h1",children:t})}),(0,l.jsx)(D.A,{children:n})]})}var W=t(4142),q=t(9169),$=t(6025);function Q(e){return(0,l.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,l.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const X={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function Y(){const e=(0,$.Ay)("/");return(0,l.jsx)("li",{className:"breadcrumbs__item",children:(0,l.jsx)(p.A,{"aria-label":(0,h.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,l.jsx)(Q,{className:X.breadcrumbHomeIcon})})})}const Z={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function J(e){let{children:n,href:t,isLast:s}=e;const a="breadcrumbs__link";return s?(0,l.jsx)("span",{className:a,itemProp:"name",children:n}):t?(0,l.jsx)(p.A,{className:a,href:t,itemProp:"item",children:(0,l.jsx)("span",{itemProp:"name",children:n})}):(0,l.jsx)("span",{className:a,children:n})}function K(e){let{children:n,active:t,index:s,addMicrodata:a}=e;return(0,l.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,u.A)("breadcrumbs__item",{"breadcrumbs__item--active":t}),children:[n,(0,l.jsx)("meta",{itemProp:"position",content:String(s+1)})]})}function ee(){const e=(0,W.OF)(),n=(0,q.Dt)();return e?(0,l.jsx)("nav",{className:(0,u.A)(j.G.docs.docBreadcrumbs,Z.breadcrumbsContainer),"aria-label":(0,h.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,l.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[n&&(0,l.jsx)(Y,{}),e.map(((n,t)=>{const s=t===e.length-1,a="category"===n.type&&n.linkUnlisted?void 0:n.href;return(0,l.jsx)(K,{active:s,index:t,addMicrodata:!!a,children:(0,l.jsx)(J,{href:a,isLast:s,children:n.label})},t)}))]})}):null}var ne=t(996);const te={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function se(e){let{children:n}=e;const t=function(){const{frontMatter:e,toc:n}=c(),t=(0,m.l)(),s=e.hide_table_of_contents,a=!s&&n.length>0;return{hidden:s,mobile:a?(0,l.jsx)(S,{}):void 0,desktop:!a||"desktop"!==t&&"ssr"!==t?void 0:(0,l.jsx)(F,{})}}(),{metadata:{unlisted:s}}=c();return(0,l.jsxs)("div",{className:"row",children:[(0,l.jsxs)("div",{className:(0,u.A)("col",!t.hidden&&te.docItemCol),children:[s&&(0,l.jsx)(ne.A,{}),(0,l.jsx)(T,{}),(0,l.jsxs)("div",{className:te.docItemContainer,children:[(0,l.jsxs)("article",{children:[(0,l.jsx)(ee,{}),(0,l.jsx)(H,{}),t.mobile,(0,l.jsx)(z,{children:n}),(0,l.jsx)(y,{})]}),(0,l.jsx)(x,{})]})]}),t.desktop&&(0,l.jsx)("div",{className:"col col--3",children:t.desktop})]})}function ae(e){const n=`docs-doc-id-${e.content.metadata.id}`,t=e.content;return(0,l.jsx)(r,{content:e.content,children:(0,l.jsxs)(a.e3,{className:n,children:[(0,l.jsx)(d,{}),(0,l.jsx)(se,{children:(0,l.jsx)(t,{})})]})})}},9022:(e,n,t)=>{t.d(n,{A:()=>l});t(6540);var s=t(4164),a=t(8774),i=t(4848);function l(e){const{permalink:n,title:t,subLabel:l,isNext:o}=e;return(0,i.jsxs)(a.A,{className:(0,s.A)("pagination-nav__link",o?"pagination-nav__link--next":"pagination-nav__link--prev"),to:n,children:[l&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:l}),(0,i.jsx)("div",{className:"pagination-nav__label",children:t})]})}},7763:(e,n,t)=>{t.d(n,{A:()=>c});t(6540);var s=t(4164),a=t(5195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var l=t(4848);const o="table-of-contents__link toc-highlight",r="table-of-contents__link--active";function c(e){let{className:n,...t}=e;return(0,l.jsx)("div",{className:(0,s.A)(i.tableOfContents,"thin-scrollbar",n),children:(0,l.jsx)(a.A,{...t,linkClassName:o,linkActiveClassName:r})})}},5195:(e,n,t)=>{t.d(n,{A:()=>b});var s=t(6540),a=t(6342);function i(e){const n=e.map((e=>({...e,parentIndex:-1,children:[]}))),t=Array(7).fill(-1);n.forEach(((e,n)=>{const s=t.slice(2,e.level);e.parentIndex=Math.max(...s),t[e.level]=n}));const s=[];return n.forEach((e=>{const{parentIndex:t,...a}=e;t>=0?n[t].children.push(a):s.push(a)})),s}function l(e){let{toc:n,minHeadingLevel:t,maxHeadingLevel:s}=e;return n.flatMap((e=>{const n=l({toc:e.children,minHeadingLevel:t,maxHeadingLevel:s});return function(e){return e.level>=t&&e.level<=s}(e)?[{...e,children:n}]:n}))}function o(e){const n=e.getBoundingClientRect();return n.top===n.bottom?o(e.parentNode):n}function r(e,n){let{anchorTopOffset:t}=n;const s=e.find((e=>o(e).top>=t));if(s){return function(e){return e.top>0&&e.bottom