UNPKG

transavormer

Version:

Transform (transcode, transmux, etc) audio/video formats using libav.js and WebCodecs

810 lines (652 loc) 45.2 kB
TransAVormer is a digital audiovisual transformation framework. To understand that, you need to understand a fair amount of digital media terminology. This document describes all digital media terms that are necessary to understand and effectively use digital media transformations. I apologize some of this comes across a bit elementary, but ask you to still read—or at least skim—the entire document. I can't know what you do and don't know. Each section of this document is subdivided into a video and audio subsection, as the details are often quite different for the two. As well as video and audio, digital multimedia files may contain subtitles and metadata, but these are not covered in this document, as they are, quite frankly, fairly trivial. # Frames Digital media is always divided in time into *frames*. Most people are accustomed to frames of video, but audio is divided into frames as well. ## Video Truly continuous video data is impractical (probably impossible), so video data is simply a sequence of pictures, fast enough to trick human persistence of vision into perceiving it as continuous information. Those individual pictures are called frames. In modern digital systems, it's usually possible for the frames to change at any rate, and even for the rate to vary depending on the needs of the scene, but in practice, almost all video is recorded at some fixed rate, expressed in frames per second. Common framerates are 24, 25, 30, 50, and 60, as well as (for weird American reasons) 24000/1001, 30000/1001, and 60000/1001. The actual light and color information in a video frame can be stored in various different formats, discussed below. The goal of a digital video system is to get frames out of a file (or protocol, stream, whatever) and onto a display at the correct rate. ## Audio For similar reasons to video, truly continuous audio data is impractical in the digital domain. Audio is pressure waves in air, so the simplest non-continuous way of storing that information is to sample the air pressure at some point rapidly, typically at least 40,000 times per second. That sequence of samples can then drive an actuator to push air and create a similar pressure sequence, recreating the audio. The device that samples audio pressure is called a microphone, and the device that reproduces it is called a speaker. The rate at which you sample audio, called the sample rate, affects the fidelity of the audio, but only to a certain point. Basically, you only need to sample at double the maximum audio frequency you want to capture. Human hearing typically goes up to around 16,000Hz, so at least 32,000 samples per second are needed to accurately reproduce everything a human can hear. Of course, a bit of headroom is needed as well, so typical sample rates are at least 40,000. 44,100 is commonly seen because it's what's used by CD audio, but it's impractical for virtually any other purpose, since it doesn't divide nicely by any of the video frame rates we saw above. Thus, 48,000 samples per second has largely displaced 44,100 as the “standard” rate, since it divides every common framerate. Even though this sample rate renders audio non-continuous, it's still impractically high for real systems. A thread that needs to produce a new sample 48,000 times a second needs to be scheduled 48,000 times a second. So, instead, audio is *also* delivered in frames, which are simply chunks of samples. Common audio frame sizes were chosen to coincide with common video frame sizes, but modern audiovisual formats don't actually depend on that, so different framerates for audio and video are common. # Formats and perception Real visual and auditory data is not digital, of course. It has to be converted into a digital form to be stored and transmitted in a computer. There are two aspects of this conversion: representation and compression. This section describes the former. ## Video Visual information in reality is extraordinarily complex. Luckily, human vision is fairly limited. The digital encoding of visual information is *always* designed to satisfy the requirements of human vision only. Each retina of the human eye captures a two-dimensional image. Human three-dimensional vision is reconstructed by the human mind from two two-dimensional images, and is very limited. On the rare occasion that video is three-dimensional, it's actually just two two-dimensional images. So, we can focus here just on two-dimensional images. In order to digitize a two-dimensional image, it is divided into pixels. Pixels are simply square (or sometimes rectangular) portions of the larger array, each of which is assigned a single color. If the pixels are small enough, then human visual acuity is unable to discern that they are small uniform squares rather than a continuous plane. ### Resolution The number of pixels in an image is its resolution. This is why cameras are described in terms of “megapixels”: that is how many (millions of) pixels are in the images they produce. Also important is the shape of the image. Most—in fact, almost all—images are rectangles, so this shape is described in terms of their aspect ratio, which is the ratio of their width to their height. For example, a 4:3 image is 4x wide and 3x tall for some x. The resolution and aspect ratio can be described simultaneously by giving the width and height of an image in pixels, for instance, 1920x1080 describes a 16:9 image with roughly 2 megapixels. Quite often, both of these properties are described as “resolution”. (Brief side note: If the pixels aren't square, then the width-by-height resolution does not, in fact, describe the image's aspect ratio. Non-square pixels are rare enough that it is usually sufficient to just mention this separately.) Unfortunately, resolutions and aspect ratios have many bizarre names, far too many of which make no sense. The most egregious family of these names is, e.g., “4K”, in which “K” seems to mean “2 megapixel”. I recommend using the width-by-height convention wherever pracical. With pixels, we know how an image is split up by space, but we still need to discuss what is actually *in* each pixel. ### Color perception Human retinae have “rod” and “cone” cells. The former distinguish light from dark, and the latter distinguish different colors. Of course, for something to have a color it must give off some light, so these are related. We will focus first on color. We do not have cone cells for every possible color of light. Rather, we only have three classes of cone cells, and thus can only see three colors. These are usually referred to as red, green, and blue, and for the purposes of this document, those will be sufficient, but note that the sensitivities of these cells don't actually align well to these colors. Alternatively to thinking of each pixel in these terms, we can think of the whole image as being decomposed into a red image, a green image, and a blue image, each of which are greyscale image that describe one color (red, green, and blue respectively) of the complete image. The way that we see the entire range of colors is by combinations. Yellow is between red and green, so when we see yellow light, both red and green cells are stimulated. As such, we can reproduce the experience of yellow light by producing red and green light simultaneously, and human vision is unable to distinguish the two phenomena. Thus, all visible colors can be represented as combinations of red, green, and blue. So, all we need for each pixel is how red it is, how green it is, and how blue it is. That is, three numbers. Numbers on a computer are represented in terms of bits, and how many bits each of red, green, and blue get is called the bit depth. Typically, each gets 8 bits. Greater bit depths aren't really needed for human vision (our vision is not that precise), but are useful for a more subtle reason: if you record with more bits, you can expand a part of that range. For instance, if it's too dark, you can lighten it while still keeping 8 bits worth of depth. As a consequence, mastered video (i.e., video ready to be played) is usually 8-bit even if the original recording was 10- or 12-bit. ### Color systems What we've just described is RGB color. But, recall our discussion of rods and cones. Humans are more sensitive the light and dark than we are to color. RGB color conflates the two, so we can't take advantage of this difference in acuity. In most practical systems, we instead use ways of describing color that separate lightness from color. Here are all of the common color systems (not yet accounting for alpha, which will be discussed later): * RGB, already described. * HSL and the closely related HSV, which stand for hue-saturation-lightness and hue-saturation-value. The distinction between lightness and value is not relevant for our purposes. HSL/HSV describe color as rotation around a hue circle, which you may have seen in drawing software. A hue of 0° is red, 120° is green, and 240° is blue. Hues past 240° are mixtures of blue and red (i.e., purples). Saturation describes the difference between a pure color and a shade of grey. Unfortunately, HSL isn't very efficient, because the hue value is meaningless if the saturation is zero (there are no colors of grey). As a consequence, HSL/HSV are often used by artists, but never used to actually store image data. * YUV and the closely related YCbCr. Y stands for luminance (somehow), i.e., lightness. U and V (or Cb and Cr) describe the color as two degrees of rotation. In short, if RGB color is the description of a color vector by its length in each axis, then YUV is a description of the same color vector by its length (Y) and rotation about two axes (U and V, or Cb and Cr). The important part is that this separates a single dimension of lightness from two dimensions of color in a more efficient way than HSL. Most images on computers use either RGB or YUV. More specifically, image files tend to use RGB, while videos tend to use YUV, though there are many exceptions (for instance, JPEG image files are actually based on YUV). All three of these color systems predate computers. RGB is human nature. HSL and HSV are by and for artists. YUV (or, more specifically, YCbCr) come from analog television. As well as color *systems*, there is the concept of color *space*. While humans see in red, green, and blue, they have different sensitivities. How the ranges of R, G, and B values map to real, physical light can be changed to cover more (or less) of the space that we can see. The two most common color spaces are often called SRGB (or JPEG) and TV. If the color space of an image is forgotten, it may be displayed slightly incorrectly, usually appearing either washed out or oversaturated. Color systems and color spaces are often conflated. ### Subsampling With non-RGB color systems in mind, we can now take advantage of humans' lesser acuity for color to reduce the amount of data needed. We do this by *subsampling* the color data, which simply means including less color data than lightness data. This is possible since the YUV color system separates lightness (Y) from color (U and V). The most common way of subsampling color is simply to have color images (U and V images) that are a quarter the size of the luminance image (that is, half in each dimension). A video player then scales that color images up and combines them with the luminance image to produce the image it actually displays. This scaling up cannot create new information, of course, so there is much less color information than luminance information. That, of course, fits with humans' reduced color acuity as compared to lightness acuity. Subsampling in this way, with the color images being a quarter the size of the luminance image, is called YUV 4:2:0. The “system” by which subsampling in this way is called “4:2:0” is so incoherent that it's better to simply memorize that “4:2:0” has that exact meaning. Even if you do choose to learn what these numbers mean, other subsampling systems use the numbers in different ways, so it may as well simply be a name. While YUV 4:2:0 is the most common, there is also YUV 4:2:2 (which has a color image that's half as wide as the luminance image but has the same height) and YUV 4:4:4 (which simply means that the color isn't subsampled). Subsampling of non-YUV color is possible but exceedingly rare. Humans are more sensitive to green than either red or blue, so some rare file formats include less red and blue information than green information. ### Putting it together Each frame in most videos includes a Y image, a U image, and a V image. These are each called a *plane* of the complete color image. If the video is YUV 4:2:0 subsampled (which most are), then the U and V images are scaled up to match the U image, and then the three are combined to create a color image. The resolution of the Y image is the resolution of the video, and the U and V images have resolutions proportional to that, depending on subsampling. A video simply consists of many frames in sequence, to be displayed at some (typically fixed) rate. ## Audio Audio is one-dimensional, which makes it considerably easier than video, but audio perception is quite interesting in ways that affect how audio is described. As described above in the frames section, audio is sampled as air pressure about 40,000 times per second. Each sample is represented as a number, and like video, each number is represented in some number of bits. Most audio has 16-bit, 24-bit, or 32-bit samples. For instance, audio CDs have 16-bit samples. There is the additional complication of integer vs. floating point samples, but that's beyond the scope of this document. Like in video, this is called the audio's bit depth. 16 bits is more than sufficient for human auditory acuity, but just like in video, it can be useful to sample with more detail so that you can expand the data later. Mastered audio (i.e., audio ready to be listened to) is usually 16-bit even if it was recorded at 24- or 32-bit. ### Volume perception While the above is a good physical description of sound, sound perception has a whole array of surprising characteristics. The first is how we perceive volume, as opposed to amplitude. The amount of air pressure carried in a sound wave dictates its volume. The raw amount of pressure is called the amplitude of the wave. But, the relationship between the amplitude and the loudness we actually perceive is not 1-to-1. If a sound has double the amplitude, it does not sound twice as loud; in fact, it only sounds a bit louder. The relationship is logarithmic. Because of this logarithmic relationship, there are different units for expressing amplitude than volume. Volume is expressed in decibels, abbreviated dB. Decibels are scaled such that (x+10)dB is 10 times the amplitude of xdB. Technically, amplitude is expressed in pascals, but this unit is irrelevant in digital audio. Digital audio adds an extra wrinkle to measuring volume (and amplitude): the volume of any part of a digital file is modulated by the device it's played on and the environment it's played in. As a consequence, volume in digital audio is always relative, and specifically relative to the loudest possible sound (greatest possible power) the speaker playing the audio can produce. As a consequence of this relative measure, the unit for amplitude is simply percent. Audio at 50% is half as loud as the speaker can play. Volume of digital audio is still measured in decibels, but 0dB is defined to be the maximum volume, which causes the unusual effect that digital audio's volume is always *negative* decibels; to get to the absolute volume when actually played, you simply add the maximum volume of the speaker. Typically, audio is in the -20dB to -15dB range on average, with peaks up to 0dB and soft parts as low as -40dB. It may seem like a strange choice to use zero to mean “as loud as possible”, but there's really no better alternative. If you have to choose a magic number, better to choose zero than some arbitrary value. Note that since decibels are a logarithmic scale, zero is *not* silence even in absolute terms. Zero amplitude cannot be measured in decibels (or, alternatively, is negative infinity decibels). ### Pitch and frequency perception Sound is a wave of pressure through air (or any other media). How we perceive that sound depends on various aspects of the shape of that wave. The closer the repetitions in the wave (the more often it goes through a complete wave), the higher in pitch the sound sounds. Double the frequency is one octave. Thus, if you double the speed of music, all the notes will be of the correct pitch, but up an octave. But, what distinguishes the sound of an oboe from a violin, or the sound of one vowel sound from another? That is the *shape* of the wave. If you were to draw the air pressure over time on a graph, with zero being the ambient pressure, then the same pitch being played on an oboe or a violin would repeat (approximately) its pattern at the same frequency, but the nuanced changes within that overall repetition would be different. Of course, both the shape and the frequency of a sound can change over time. The most basic shape for a sound wave to have is the sinusoidal wave, or sine wave, which is simply the mathematical sine function. The sound of a sinusoidal wave is pleasant but fairly dull, and sine waves are hard to hear among other sounds. Now is where things get the most interesting: any shape of a wave can also be described as the sum of many simple waves. In fact, the trained musician can hear these compounded waves; they are called the *overtones* of a sound. The character of the overtones that an instrument, voice, or indeed anything else creates is called its *timbre* (pronounced “tamber” because the French language is even more ludicrous than English). (Brief side note: to actually use this for digital representation, you also need the “phase” of each overtone. But, these details are considered far beyond the point of this document.) Whether a complex waveform is the sum of its overtones or a complex shape is a matter of interpretation, and neither interpretation is more correct than the other. However, describing it as the sum of its overtones does have an advantage: all sound can be described as the sum of many frequencies over time. If you've ever seen a spectrogram of audio, you've seen this representation. One of the most fascinating things about thinking of sound in this way is that frequency is just the reciprocal of seconds, so frequency over time is per-seconds-per-second. There is some dividing line (really, more of a blurry dividing area) where pulses stop sounding individual and start sounding like a tone; human hearing interprets small timescales radically differently than large timescales. Digital audio data can be represented by individual samples or by frequencies, but ultimately it has to be converted to samples to be played by a speaker. This conversion is called an inverse Fourier transform, and the transformation from samples to frequencies is, of course, called a Fourier transform. ### Stereo and surround sound Humans have two ears (wow!). Thus, all location information we are capable of discerning comes from only two locations. The way that the brain converts just two signals into an (albeit rough) three-dimensional map of the soundscape we're in is extraordinarily complicated. To try to account for this, audio usually has more than one *channel*. e.g., stereo audio has a channel for the left ear and a channel for the right ear. Surround-sound audio will further separate left-front from left-back, etc. Ultimately, each channel is just its own sequence of samples, all side-by-side. Since humans have only two ears, it may seem redundant to have more than two channels, but it's not. If you're listening to audio in headphones, then essentially each channel goes to one ear, but if you're listening to it on speakers, then how it reaches your ears is affected by the environment. Ultimately, audio “intended” for headphones *cannot* be correct, because everyone's environment (and even just head size and shape) is different. Common sets of channels have short (stupid) names of the form *x.0* or *x.1*. *x* is the number of speakers, excluding any subwoofer. *.0* means there is no subwoofer channel, and *.1* means that there is. Common configurations, other than 1.0 (monaural) and 2.0 (stereo) are 4.0, 5.0, 5.1, and 7.1. # Packets and compression Video data is so outlandishly large, compressing it is essentially mandatory. Audio data isn't anywhere near as large, but it's still big enough to be worthy of compression. A method of compression (and decompression) is called an *encoding*, and a piece of software to perform this compression is therefore called an *encoder* (and the reverse a *decoder*). A piece of software that does both is a *codec*, which is short for (en)coder-decoder. It used to be common to conflate codecs (which are particular implementations of encodings) with encodings; for instance, “DivX” is a codec, not an encoding, but files encoded with DivX were called DivX files, not MPEG-4 video files. Luckily, that habit seems to have largely vanished, and modern video encodings are given their proper name, rather than the name of the software that encoded them. Sometimes encodings are also called “formats”, and this term isn't wrong, but “encoding” is more specific. Most encoders express their data in frames, just like the data they're encoding. There is no universal name for an encoded frame of data, but this document (and TransAVormer) will call them *packets*, following the standard set by FFmpeg and libav. Other sources may call them “chunks”, or simply “encoded frames”. There are two broad categories of compression, for both video and audio: lossless or lossy. Lossless compression is exactly what it sounds like: data takes less space, but loses no fidelity. This is possible because a lot of data is fairly boring; imagine trying to explain a black screen, vs. trying to describe a complex image. Data which is simpler usually takes less space to describe, even flawlessly (losslessly). Note that there is an unrelated source of loss implied by the above discussions of *depth*: if you take, for example, 8-bit RGB video data and convert it to 3-bit YUV 4:2:0 video data, you will lose information, but not because of compression. A lossless compression encoding is not considered lossy simply because it doesn't support the depth you wish to encode. Lossless compression is better than nothing, but it can usually only achieve around 33% the size of the original data. That's quite good, but AV data is *quite* big. Ultimately, the lossless nature of lossless compression restricts its creativity, and so there are fewer lossless techniques for compressing media data than there are lossy techniques, and their efficacy is mostly similar. If you need lossless compression, then for audio, FLAC is widely supported, but WavPack supports more bit depths. For video, some lossy video encoders (which will be discussed below) also support a lossless mode, and it is also possible to use lossless image encodings, such as PNG, as video frame encodings. Lossy compression achieves smaller sizes by voluntarily losing information. Of course, this means that it loses quality. All advancements in lossy compression revolve around minimizing size while maximizing the quality of the data still retained. Generally, there is a human factor as well: the quality is the quality according to human perception, not according to a strict mathematical model of loss. Because it loses quality, there is a tradeoff in lossy compression between space (size taken by the encoded data) and quality (how much of the original data is preserved). The most common way to express this is *bitrate*, i.e., how many bits are taken for one second of audio or video. As technology advances, lossy compression improves, and less bitrate is required to achieve the same quality, yet it's quality that viewers see or hear, so describing quality as “one megabit” means something very different for an encoding from 1995 than it does for an encoding from 2020. More subtly, how much space it takes to describe some detail depends on how complex the detail is. Thus, the same amount of space that is sufficient to describe one image or sound in near-perfect detail may be inadequate for another image or sound. In particular, random noise is very difficult to encode, and solid areas of color or silence or held tones are very easy. Thus, it's usually better to fix the quality rather than the bitrate. Many encodings allow you to fix either of these properties. If you fix the size but allow the quality to fluctuate, this is called constant-bitrate encoding. If you fix the quality but allow the size to fluctuate, this is called constant-quality encoding. ## Video There are two core techniques involved in (lossily) compressing video data: intraframe compression, and interframe compression. ### Intraframe compression Intraframe compression (i.e., compressing a single frame using only its own data) is fundamentally the same problem as compressing image files. The simplest video encodings, in fact, are exactly that: just a sequence of frames each compressed independently. An example of this style is MJPEG (motion JPEG), which is simply a JPEG image file for each frame. The best way to understand how intraframe compression works is simply to do it badly. Save a JPEG file with very low quality (say, 1%), then open it again. What you'll see is a lot of 8-by-8 blocks. Some of them will just be one solid color; others will have simple gradients. Virtually all intraframe image/video compression encodings use this same concept: break the image down into blocks of some fixed size (called *macroblocks*), then describe each block in relation to some expected pattern, such as a solid field or gradient. Since the JPEG image in this example was saved with the lowest possible quality, it gave as short (and thus small) of a description as it could, and thus lost a lot of information. The more space you use for these descriptions, the more quality is preserved. While virtually all intraframe image and video compression encodings use macroblocks, the details *beyond* that are incredibly diverse. Typically there are larger and/or smaller blocks describing less/more precise detail, and of course, exactly how the detail within each block is described varies considerably from encoding to encoding. ### Interframe compression In a video, frames are not independent from each other. Typically, if frame B follows frame A, then it will be substantially similar to frame A, but with some changes. If frame C follows frame B, then it's likely that some of the changes between A and B will continue onto C, if you consider changes such as motion—an object in motion remains in motion, of course. This logic underpins how video data is stored. Video is stored in “intraframes” and “progressive frames”, usually abbreviated as I-frames and P-frames. I-frames are stored as described above, in the “intraframe compression” section. But the data stored for a P-frame is not sufficient to describe the entire frame. Instead, a P-frame describes the changes from the previous frame, as motion vectors as well as changes in lightness and color. Thus, for instance, if one figure is moving in the frame but others are still, the P-frame will describe the motion, but will describe nothing at all about the other characters. The image for non-moving characters is instead just carried over from the most recent I-frame. If you've ever seen a so-called “datamoshed” video, you've seen the P-frame divorced from its (correct) I-frame, which lets you see and understand this motion data. Since P-frames depend on their most recent I-frame, there is usually a degredation of quality over time. If you have 600 P-frames in a row, the last one, even decoded correctly, will not look as good as the I-frame. Thus, P-frames don't continue indefinitely. At the very least, a decent encoder will put a new I-frame when the scene changes dramatically (so, everything changes), but there is typically also a maximum time between I-frames, usually less than a minute. The period between I-frames is called the “keyframe interval”, and the set of images that all depend on a given I-frame (plus the I-frame itself) is called a “group of pictures”. Also because P-frames depend on their most recent I-frame, it is impossible to open a file to a random frame and decode successfully from there. You must open to an I-frame and start from there. It is thus common for file formats to contain an index that describes where to find all the I-frames. There is no universal rule of thumb about how large an I-frame is as compared to how large a P-frame is. Both take as much space as the quality requires of them, and as much space as the data requires of them. But, typically, one can expect I-frames to be hundreds of times the size of P-frames. As well as P-frames, some codecs support “B-frames” (before-frames?), which are simply P-frames reversed. That is, they describe a frame that comes *before* an I-frame. This means that the frames have to be encoded out of order, as you must decode the later I-frame first, but allows the maximum quality (the I-frame) to be placed nearer to the middle of the group of pictures instead of at the beginning. Since the quality of a P-frame degrades in relation to its distance from the I-frame, placing the I-frame in the middle allows less loss. In practice, however, the I-frame is usually only one to four frames into a GOP, as processing many B-frames to be able to display the first one takes time. ### Common encodings Which encoding is common at any given time changes as technology evolves. Thankfully, video formats found commonly have kept up as video encoding techniques have improved. Historically, the Misanthropic Patent Extortion Gang (MPEG) dominated the entire space of video encodings, and many of their encodings remain popular. Very few organizations or people in this world are unambiguously evil, but MPEG is one of them. MPEG does not develop anything; they are a consortium that pools ideas (and patents), and as time has gone on, their priority has changed from pooling the best ideas to pooling the ideas most encumbered by the most patents. MPEG technology should be avoided wherever possible. A modern video codec that is just starting (as of the writing of this document) to get widespred use is AV1. AV1 was created by the Alliance for Open Media, a consortium created as a response to MPEG, and is unencumbered by patents. On the web, the VP9 codec is still quite popular; it was created by Google to be an open codec, and while it was perfectly acceptable for its time, it's not especially remarkable as compared to AV1. VP9's predecessor was VP8, but VP8 had less uptake. MPEG's most recent codecs are named H.`some number`, e.g., H.265. H.266 technically exists, but MPEG has become a joke, so no one uses it. H.265's patent situation is so absurd that it's not clear if there is any legal way for an entity that's not in MPEG to use it; it got a small amount of uptake in certain industrial standards (including digital TV), but little else. H.264 is enormously popular, but is still encumbered by patents. H.264 is probably the most popular video codec as of the time of this writing. H.264's predecessor is H.263 (wow!), but the MPEG codec based on H.263 is slightly changed, so it doesn't have that name. It's officially called MPEG-4 Part 2, but it's widely known by the name of a popular codec, DivX. Though DivX was enormously popular in its time, it is now all but dead. The predecessor to H.263 was H.262, which is also known as MPEG-2 Part 2 or MPEG-2 video, and its predecessor is H.261, also known as MPEG-1 Part 2 or MPEG-1 video. Before H.264 became popular, there were hundreds of minor video codecs used for special purposes. Nowadays, virtually all video is H.264, AV1, or VP9. ## Audio There is no similar concept of intra- and inter-frame compression in audio. All audio data is described as changes, but it's valid to start from anywhere, as the effect of describing audio data as a change from nothing is usually to simply fade in. The core concept behind lossy compression of audio is describing the overtones in as little detail as is feasible. The simplest (and worst) audio compression imaginable would simply perform a Fourier transform, then choose only the loudest overtones to describe per each frame. In practice, on top of this, you must allow tones to change over the course of a frame, and the loudest overtones are not necessarily the correct ones for human perception. You may have heard buzzing or ringing sounds in badly compressed audio. These sounds are the result of removing overtones, which results in the remaining tones being “naked”, so to speak, which makes them more noticeable. Beyond this basic concept of performing a Fourier transform and analyzing the overtones, audio encodings are astonishingly diverse. Most have some concept of “psychoacoustics”, i.e., how they describe sound is influenced by the psychology of audio perception. Some even have different models for voice than for other sounds. While audio data does not have distinct I-frames and P-frames, the data is nonetheless described in terms of how it's changed from the previous frame. When seeking in a file, the codec generally assumes that the previous frame was silent. It rarely takes more than 60ms worth of data for this false start to no longer have any effect on the audio, but some audio encodings define this interval more precisely. An audio processor should choose whether to start decoding early (so as to get the audio data more correct) based on its intended use, as this is less important for playback than for, e.g., compositing audio. ### Common encodings Like with video, for a time, audio encoding was dominated by the Misanthropic Patent Extortion Gang (MPEG). Unfortunately, there's a far stupider problem that has infected the world of audio. For some reason, a lot of people have gotten stuck to MP3 (which is an abbreviation of MPEG-1 Layer 3 Part 3), which is such an outlandishly ancient codec that its successor's successor's successor's successor has been obsolete for over a decade. [Friends don't let friends use MP3](https://ecastr.com/rants/mp3/). When people aren't stuck in the MP3 timewarp, the popular options are an open codec named Opus, and MPEG's AAC. I would hesitate to even guess which of these two is more popular, since the whole space is awash in MP3 nonsense. Opus is just plain better than AAC. Other than some experiments in using AI for audio codecs, no one has matched Opus's quality-per-bitrate as of the time of this writing. However, it is restricted to stereo or mono audio. AAC remains popular probably because of its association (by way of MPEG) with H.264, as well as because it's the format used by iTunes. AAC has many sub-versions with weird names (AAC-LE, HE-AAC, HE-AACv2, etc etc), so it is actually many encodings over time, all given a single name. Prior to Opus, the popular non-patent-encumbered audio codec was Vorbis. Vorbis was actually quite popular in video games, because video game developers don't want to deal with patents any more than you do. Nowadays, Vorbis has been almost completely replaced by Opus. # Multiplexing and file formats If all you have is video, or all you have is audio, then in theory the way that data could be written to disk or communicated across a network is to simply place each packet, one-by-one, in the order that they are to appear (or, in the case of B-frames, in the order that they are to be decoded). Then, you would simply need some header to say what kind of data it is, and the data could be decoded. But, if you want audio *and* video data, then it's generally less practical to store them as two separate files than it is to put them together in one. Thus, we need a way of interleaving video and audio data together, so that it can be read and decoded in the right order for the video and audio to correspond correctly when presented. Indeed, this concept of interleaving audio and video data is immortalized in the name of one of the classic file formats for this task: AVI stands for Audio Video Interleave. This interleaving process is also called *multiplexing*, and extracting the packets from a multiplexed file is called *demultiplexing*. In order to know when to present data, a multiplexing format must at least provide a timestamp for every frame. And, of course, it will ideally put them in timestamp order (or, in the case of B-frames, in the order they need to be decoded). These timestamps will be given in some *timebase*. For instance, if the timebase is 1/1000, then the timestamps are in milliseconds. Almost no multiplexing formats are restricted to only one codec. As a consequence, if all you know is that a file is, for instance, a .avi file, you have no way of knowing its quality. There's a lot of “common wisdom” about which media file formats are better than others in terms of quality, but it's all hokum. A .avi file with AV1 data in it is just as high in quality as that AV1 data in any other file. Unfortunately, there is simply no way to know from a file extension anything about the quality of the data inside. The goals of a media file format are: * To store audio and video data—in some cases as well as other data such as subtitles—in an order that is conducive to decoding and presenting. * To store enough metadata about the data that the correct codec can be found and initialized. The metadata required to initialize a codec is called the “extradata” in FFmpeg/libav terms, and the “description” in WebCodecs terms, but it is completely codec-specific. Any given format might have additional goals, such as * Streamability. This doesn't necessarily refer to streaming in the sense of streaming video over a network, but to the ability to write the data in order from start to finish without having to go back. The reason why a format might *not* be streamable is indexing, our next goal. * Seekability. A format is seekable if you can jump to a given time within the file and play from there. Remember, each encoded frame takes a different amount of space, so we cannot simply blindly jump into the middle of the file. Most file formats include an *index* that contains information on which locations in the file correspond to which time. Without an index, it is either necessary to be able to distinguish a packet from other data (so that you can grope around in the file for a packet), or to start from the beginning every time you read the file. Even without an index, most formats provide some way to find a packet in the middle of the file, so that you can seek by dead reckoning. * Networkability. If data is intended to be sent over a network, it's valuable to (a) make sure that there is some exact correspondence between data packets and network packets, and (b) be able to distinguish crucial packets (I-frames) from best-effort packets (P-frames). If I-frames are lost, the video can't be played; if P-frames are lost, you miss a frame. These goals often conflict, and the bikeshedding of these goals is why there are such a staggering number of media file formats. Three of the major ones will be discussed here. ## MPEG-4/ISOBMF MPEG-4's container format (usual extension .mp4) is a chimera of a format, with at least two common names other than MPEG-4: the ISO Base Media Format (ISOBMF) and Apple MOV. It's called Apple MOV because it was actually Apple's MOV format long before it became standardized as MPEG-4—remember, MPEG doesn't actually make anything, they just gather things others have made. It's called ISOBMF because it was *also* standardized by the International Standards Organization. Technically these standards vary slightly, but only in what encodings the data contained within are allowed to have. The MPEG-4 standard itself only describes MPEG-4 files with MPEG-4 data. Apple's MOV additionally allows various Apple encodings. ISOBMF is the most broad, and describes how to include lots of encodings. All of them are nonetheless typically named .mp4, so I'll refer to all of them as MPEG-4. MPEG-4 is seekable. It's possible to write an MPEG-4 file with the index at the beginning, in which case it's also networkable, but this is often not the default, because the index is only known at the end. In FFmpeg/libav, for example, you must set the `movflags` option to `faststart` to move the index to the beginning. MPEG-4 is not streamable. It is not safe to record data to MPEG-4 data “live”, in a streaming manner, because if the recording is cut off for any reason and the index is not written, the data is usually unrecoverable. Many a naïve user has lost hours of recording data due to using this unsuitable format for recording. Note that this fact isn't actually a complaint about MPEG-4; it's fine for different formats to have different purposes. Video streams in MPEG-4 can have various timebases. Audio streams have the reciprocal of the sample rate as their timebase. Note that this means that different streams may have different timebases. ### Quasi-aside: ISMV ISMV is a subformat of MPEG-4 created by Microsoft to make MPEG-4 streamable. In short, it makes an MPEG-4-like streamable file by (sort of) treating every frame as a complete file with its own metadata. This modification isn't technically allowed by the MPEG-4 standard, so ISMV files aren't technically MPEG-4 files. But, virtually all if not all readers capable of reading MPEG-4 will read ISMV files just fine, so if you need the MPEG-4 format but you also need streamability, ISMV will usually suffice. ## Matroska/WebM Matroska (usual extension .mkv) is a format that was created to be very general. Virtually all encodings can be stored in Matroska, and for any encoding that doesn't have a defined way of storing it in Matroska, it is almost certain that someone will define it. As a consequence of Matroska's generalness, seeing a .mkv file tells you even less about what's in it than seeing a .mp4 file. To make things more predictable, Google created a restricted subset of Matroska called WebM. WebM may only contain certain video and audio codecs. Periodically the list is amended, but at the time of this writing, the supported video codecs are AV1, VP9, and VP8, and the supported audio codecs are Opus and Vorbis. Other than that restriction (and the removal of an optional component in Matroska that's not relevant here), Matroska and WebM are the same. All WebM files are valid Matroska files. Because of solving-too-many-problems-ism, many features of Matroska aren't guaranteed in all Matroska files. Matroska is *usually* seekable, but the index is technically optional. Usually the index would only be missing if the file was recorded live and the recording was cut off without ending cleanly. Matroska is streamable and networkable. Streamed Matroska files will only be correctly seekable of the index is correctly written at the end. All streams in Matroska use milliseconds as the timebase. This is, frankly, inadequate, and players usually have to be careful about timing to make sure things remain seamless. ## Ogg Ogg (extensions include .ogg, .ogv, .oga, and .opus) is a format that was created to be astonishingly simple. This crash course has only scratched the surface of the concerns involved in most of these formats, but we've covered all the concerns required by Ogg. While Ogg is not especially popular, it has some small popularity from its association with several well-known encodings. Vorbis files were almost always distributed in the Ogg format, and Opus files that don't have video are distributed as Ogg with reasonable frequency, though using WebM for this purpose is common as well. Only a few encodings are supported in Ogg, and in particular, very few video encodings are supported. Ogg has no index, but has facilities to find a packet in the middle of a file, making it somewhat seekable. Ogg is streamable and designed to be easily adapted to the network. Ogg itself does not define what timebase any stream should use. Instead, the documentation for embedding each encoding into Ogg is expected to document the timebase to use. Typically, fixed-framerate video uses the reciprocal of the framerate as its timebase, and variable-framerate video will have various timebases depending on the encoding. Audio usually uses the reciprocal of its sample rate as its timebase.