A video codec is software or hardware that compresses video for sending and decompresses it for playback. H.264 and VP8 run almost everywhere at low CPU cost. VP9 and AV1 compress better but need more processing power. VideoSDK supports all four and falls back to VP8 automatically when a device cannot handle the codec you chose.
Before the first frame of a video call reaches your screen, the devices on each end have already agreed on a video codec. That agreement decides how much bandwidth the call uses, how warm the phone gets, and whether a group call can adapt when one participant drops to a weak connection.
Most codec explainers are written for files and streaming, where a server encodes once and viewers only decode. Real-time video breaks that model. Every participant encodes live on their own device and decodes everyone else, and one unsupported codec can turn a tile black.
This guide covers what a video codec is, how H.264, VP8, VP9, and AV1 compare in VideoSDK's own codec table, which one to pick for which job, and how to set it in code.
What is a video codec?
A video codec shrinks raw camera frames roughly 160 to 330 times so they fit through a network, then rebuilds them on arrival.
A video codec is defined as software or hardware that encodes digital video into a compact bitstream and decodes that bitstream back into frames for display. The name is a contraction of coder-decoder. H.264, VP8, VP9, and AV1 are all video codecs, and each one defines its own rules for how the compression works.
In a video call, the codec runs on every participant's device: once to encode their own camera and once for every other feed they decode. VideoSDK exposes the codec as a per-track option on createCameraVideoTrack(), supports VP8, H.264, VP9, and AV1, and uses VP8 by default, a codec every WebRTC browser is required to implement.
A video codec works by discarding information your eyes will not miss and describing the rest as efficiently as possible. The two subsections below show why that matters and how it is done.
Why video needs a codec
Uncompressed video is far too large to send. A single raw 720p camera feed would overwhelm almost any home or mobile connection.
A codec shrinks that feed to a small fraction of its size. VideoSDK's default 720p profile, h720p_w1280p, sends it at about 1.5 Mbps, according to the encoder table in VideoSDK's docs. That reduction is what makes a video call possible at all.
How a video codec compresses frames
Every modern video codec uses the same three techniques, in different proportions.
- Intra-frame (spatial) compression. A keyframe is compressed on its own, like a photo, by predicting each block of pixels from its neighbours in the same frame. Keyframes are expensive, so encoders send them sparingly.
- Inter-frame (temporal) compression. Most frames are described as changes from an earlier frame. The encoder finds where each block moved (a motion vector) and sends the movement plus the small difference left over. A talking head on a still background compresses extremely well for this reason.
- Quantization. The encoder rounds away fine detail. This is the lossy step, and it is where the bitrate target is enforced: a lower bitrate means coarser rounding and a softer picture.
Newer codecs win by giving the encoder more options for all three: more flexible block sizes, more prediction modes, better filtering. More options mean better compression and more work for the encoder, and that trade-off sits behind every row of the comparison table later in this guide.
In short, a video codec is the compression contract between sender and receiver, and every codec trades encoder effort for bitrate.
Codec vs Container vs Encoder
A codec defines the compression, a container packages the result into a file, and an encoder is the software or chip that does the compressing.
The three terms get used interchangeably, which is why "Is MP4 a video codec?" appears in search results for this topic. It is not. MP4 is a container, and it can hold H.264, VP9, or AV1 video, according to MDN's web video codec guide.
| Term | What it is | Examples | What it decides |
|---|---|---|---|
| Codec (video coding format) | The compression standard: the rules for turning frames into a bitstream and back | H.264, VP8, VP9, AV1 | Bitrate at a given quality, CPU cost, and which devices can decode the stream |
| Container | The wrapper that stores encoded video, audio, and metadata together in one file | MP4, WebM, MKV | Which players and platforms accept the file, plus seeking, subtitles, and chapters |
| Encoder | One implementation of a codec, in software or dedicated hardware | x264 and Cisco's OpenH264 for H.264, libvpx for VP8 and VP9, the video blocks inside phone chips | Encoding speed, power draw, and how much quality it extracts from the same codec |
The formal name for the first row is a video coding format: the specification of the bitstream. H.264 is a video coding format, and x264 is an encoder that produces it. Two encoders for the same codec can give visibly different quality at the same bitrate, because the standard defines what a decoder must understand, not how hard the encoder searches for a good encoding.
Real-time calls add a twist. A WebRTC call has no container while it runs: encoded frames travel as RTP packets straight to the other side. The codec format video calls negotiate is the only one of the three that both ends must agree on. A container only enters the picture when you record the call to a file.
WebM is the container you will meet most often next to VP8, VP9, and AV1, and MP4 is H.264's usual home. If file packaging is your actual question, see MKV vs MP4. For how codec, container, and network each affect picture quality, see video quality explained: bandwidth, codecs, and containers.
Keep the three apart and most codec confusion disappears: choose the codec for the network and devices, the container for the destination, and the encoder for speed and power.
H.264 vs VP8 vs VP9 vs AV1
VP8 and H.264 trade compression for reach and low CPU cost, while VP9 and AV1 trade CPU and simulcast for better compression.
The table below reproduces the substance of the codec guidance in VideoSDK's documentation, which rates each codec on the same five criteria. It is the most useful single view of these four codecs for real-time video, because it includes the column most comparisons leave out: whether the codec supports simulcast.
| Codec | Quality and compression | CPU cost | Device and browser support | Simulcast (multiStream) | Recommended use |
|---|---|---|---|---|---|
| VP8 | Good | Low | Very broad | Supported | Default choice for maximum compatibility |
| H.264 | Good | Low | Broad | Supported on web, single-stream on iOS | Mobile and enterprise environments |
| VP9 | Better | Medium to high | Modern browsers | Not supported | Improved quality on modern devices |
| AV1 | Best | High, reduced by hardware acceleration | Growing | Not supported | Highest quality where supported |
Source: VideoSDK optimize video track guide for the React SDK, read September 10, 2026. The iOS version of the guide lists H.264 as single-stream.
The simulcast column is the one that bites in production. Pass VP9 or AV1 with multiStream: true and VideoSDK switches multiStream off and emits ERROR_MULTISTREAM_NOT_SUPPORTED, so every receiver gets the same single layer regardless of their connection.
Codec origins, licensing, and WebRTC status
| Codec | First published | Developed by | Licensing | WebRTC status |
|---|---|---|---|---|
| H.264 (AVC) | 2003 | ITU-T and MPEG | Patent-licensed through Via LA; Cisco does not pass royalties on for its OpenH264 binary | Mandatory in browsers (RFC 7742) |
| VP8 | 2010 | Google, released through the WebM Project | Royalty-free | Mandatory in browsers (RFC 7742) |
| VP9 | 2013 | Royalty-free | Optional: Chrome 48+ and Firefox | |
| AV1 | 2018 | Alliance for Open Media | Royalty-free | Optional: Chrome 113+ and Firefox 136+ |
Sources: publication years from the ITU-T H.264 recommendation, the WebM Project announcement, and the Meta, Vodafone, and YouTube AV1 white paper. Licensing from MDN and OpenH264. WebRTC support from MDN's WebRTC codec guide and RFC 7742.
H.264: the codec every device already has
H.264, also called AVC, is the oldest codec in this comparison, supported in close to 100% of smartphones according to the 2025 white paper from Meta, Vodafone, and YouTube. RFC 7742 requires every WebRTC browser to implement its Constrained Baseline profile, so an H.264 call can always be negotiated.
Its advantage on mobile is hardware. MDN notes that on iOS and iPadOS, H.264 can be encoded and decoded in hardware. The catch is licensing: H.264 is patent-encumbered, although Cisco's OpenH264 binary removes the royalty question for most WebRTC apps.
VP8: WebRTC's default codec
VP8 is Google's royalty-free codec, open-sourced in May 2010 through the WebM Project and, like H.264, mandatory in every WebRTC browser. VideoSDK uses VP8 as its default and as the fallback it switches to whenever another codec fails.
Its compression is on par with H.264, and VideoSDK's table rates both "Good." Its weakness is Apple hardware: MDN states VP8 has no hardware support on iOS, which increases processor load and reduces battery life.
VP9: better compression, single-stream in VideoSDK
VP9 is VP8's successor, finalized by Google in 2013 and royalty-free. VideoSDK rates its compression "Better" than VP8 and H.264, at a medium-to-high CPU cost. WebRTC support covers Chrome 48 and later plus Firefox, per MDN.
In VideoSDK, VP9 runs single-stream, so it suits calls where every receiver has a similar connection: one-to-one calls, or small meetings on known networks.
AV1: the best compression at the highest CPU cost
AV1 is the Alliance for Open Media's royalty-free codec, first published in 2018. The Meta, Vodafone, and YouTube white paper puts its gain at up to 30% better compression than VP9, and MDN cites compression rates as much as 50% higher than H.264. For a longer look at that pairing, see AV1 vs H.264.
That efficiency costs compute, which is why VideoSDK rates AV1's CPU cost as high. VideoSDK's docs also carry a warning from its own testing: AV1 failed on some versions of Safari on macOS and on mobile web on iPhone, in both Chrome and Safari. Test it on your target devices before shipping it.
Where H.265 fits
H.265 (HEVC) is missing from this comparison because VideoSDK's codec option does not offer it: the four choices are VP8, H.264, VP9, and AV1. For recorded and broadcast workflows where H.265 comes up, see H.264 vs H.265, which also covers its uneven WebRTC support.
On raw compression AV1 wins; on reach, CPU cost, and simulcast, VP8 and H.264 still win for most live calls.
Which codec should you use?
Use VP8 or H.264 for most live calls, and save VP9 and AV1 for known devices where bandwidth is the binding constraint.
The right video codec depends less on which one compresses best and more on who is sending, who is receiving, and whether the call needs to adapt to different connections. Use this list as a starting point:
- Use VP8 when you do not control the clients. It is VideoSDK's default, rated "Very broad" for support, keeps simulcast, and is the codec every other choice falls back to anyway.
- Use H.264 when your audience is mostly on iPhones or enterprise networks. Hardware encode and decode on iOS saves battery, per MDN, and VideoSDK's docs recommend it for mobile and enterprise environments. On VideoSDK's iOS SDK, H.264 runs single-stream, so plan group-call layouts around that.
- Use VP9 for one-to-one or small calls on modern desktop browsers. With one receiver, losing simulcast costs little, and you get better quality per bit.
- Use AV1 when you control the hardware and have tested it. Meeting-room devices, kiosks, or a desktop app on recent machines are good candidates. Mobile web is not, given the iPhone failures in VideoSDK's own testing.
- Use AV1 or VP9 for recorded and on-demand video. Encoding offline removes the real-time CPU limit. Over 75% of YouTube's catalog, weighted by watch time, is available in AV1, according to the Meta, Vodafone, and YouTube white paper.
The mistake: AV1 in a large group call
The most expensive codec mistake in real-time apps is choosing the best-compressing codec for a large group call. With multiStream on, VideoSDK sends 720p, 360p, and 180p layers from a 720p camera, so each viewer receives the layer their bandwidth can carry. VP9 and AV1 turn that off.
Without simulcast, one layer serves everyone. The participant on a weak mobile connection receives the same stream as the one on office fibre, and the more receivers a call has, the more likely one of them is on a poor connection. In practice, better compression per stream rarely makes up for losing adaptation across every receiver. For why raw bandwidth is not the whole story, see bandwidth vs latency.
The short version: default to VP8 or H.264, and treat VP9 and AV1 as targeted upgrades for call types you have measured.
Setting the codec in a real-time SDK
In VideoSDK, the codec is one option on the camera track, and the SDK handles fallback when a device cannot use it.
The examples below use VideoSDK's JavaScript SDK, which added the codec option in version 0.10.2 on June 5, 2026. The npm registry listed version 1.1.1 as current on September 10, 2026. Load the SDK from its CDN script tag or with npm install @videosdk.live/js-sdk; the docs reference it as the global VideoSDK.
Choose the codec on the camera track
Pass codec to createCameraVideoTrack(). This track asks for H.264 at 720p with three simulcast layers:
const cameraTrack = await VideoSDK.createCameraVideoTrack({
encoderConfig: "h720p_w1280p",
optimizationMode: "motion",
bitrateMode: VideoSDK.Constants.BitrateMode.BALANCED,
multiStream: true,
maxLayer: 3,
codec: VideoSDK.Constants.VideoCodec.H264,
});
codec takes a value from VideoSDK.Constants.VideoCodec: VP8 (the default), H264, VP9, or AV1. H.264 is used here because, in the JavaScript SDK, it keeps multiStream on. Swap in VP9 or AV1 and VideoSDK turns multiStream off and emits ERROR_MULTISTREAM_NOT_SUPPORTED, which also makes maxLayer irrelevant, since it only applies when multiStream is on.
Handle the codec-changed event
Pass the track to initMeeting(), then register listeners before joining so no event is missed. The token comes from your server, never from the browser; see VideoSDK authentication and tokens. Run this inside an async function, as the quickstart does.
VideoSDK.config(TOKEN); // minted on your server
const meeting = VideoSDK.initMeeting({
meetingId: MEETING_ID,
name: "Ada",
webcamEnabled: true,
customCameraVideoTrack: cameraTrack,
codecSwitchEnabled: true, // default: fall back to VP8 instead of a black tile
});
meeting.on("error", (error) => {
if (error.code === "ERROR_VIDEO_PRODUCE_CODEC_NOT_SUPPORTED") {
// This device can't encode the chosen codec; VideoSDK is sending VP8
}
if (error.code === "CODEC_NOT_SUPPORTED") {
// This device can't decode the meeting's codec; a switch to VP8 follows
}
});
meeting.on("codec-changed", (data) => {
console.log("Current codec:", data.currentCodec);
console.log("Previous codec:", data.previousCodec);
console.log("Unsupported remote codec:", data.unsupportedRemoteCodec);
console.log("Kind:", data.kind);
console.log("Caused by participant:", data.causedBy);
});
await meeting.join();
Two fallbacks are at work here, and both end in VP8, the codec video calls in VideoSDK always return to:
- Sending side. If this device cannot encode H.264, VideoSDK switches its track to VP8 and emits
ERROR_VIDEO_PRODUCE_CODEC_NOT_SUPPORTED. The call continues. - Receiving side. If a participant joins whose device cannot decode the meeting's codec, that participant gets
CODEC_NOT_SUPPORTED. VideoSDK then moves every participant to VP8, and everyone receivescodec-changedwith the previous codec, the new one, the unsupported codec, the media kind, and the participant who caused the switch.
The switch is controlled by codecSwitchEnabled in initMeeting(), which defaults to true. Set it to false and VideoSDK will not fall back, and the docs warn that affected participants may see a black screen instead of video. Leave it on unless you are testing codec support deliberately.
The practical value of codec-changed is visibility. Send it to your analytics along with causedBy, and you learn which devices in your user base cannot handle the codec you chose. That is better evidence for a codec decision than any compatibility table, including the ones above. The full payload is listed in the codec-changed API reference.
Not using JavaScript? The React SDK exposes the same event as onCodecChanged on the useMeeting hook, and the iOS SDK as onCodecChanged on MeetingEventListener. See the React and iOS versions of the optimize video track guide. One platform difference to plan for: VideoSDK's iOS guide lists H.264 as single-stream, like VP9 and AV1.
Audio codecs
Every WebRTC endpoint must implement two audio codecs, Opus and G.711, under RFC 7874, published by the IETF in May 2016.
Audio gets far less attention than video in codec discussions, because in a video call it rarely needs a decision. It does need one the moment a call touches the phone network.
Opus: the default for real-time audio
Opus was standardized as RFC 6716 in September 2012. It scales from narrowband speech at 6 kbit/s to high-quality stereo music at 510 kbit/s, with frame sizes from 2.5 to 60 ms. MDN's WebRTC codec guide suggests 16 to 20 kbps for wideband speech and 28 to 40 kbps for fullband.
That range is why video calls rarely need an audio codec decision: Opus handles a quiet one-to-one and a live music lesson with the same codec. VideoSDK's Telnyx SIP integration guide tells you to choose Opus and set it as the first priority.
G.711: the codec of the telephone network
G.711 is the pulse-code modulation format of the public telephone network: 8-bit samples at 8,000 Hz, which works out to 64 kbps. MDN describes its quality as generally poor by modern standards and treats it as a least-common-denominator fallback. It survives as the lowest common denominator across SIP trunks and PBXs.
At 64 kbps, G.711 uses 3 to 4 times the bitrate of wideband Opus to carry narrowband audio. When the phone leg of a call runs G.711, that leg is narrowband no matter what the WebRTC side uses, which is why phone callers sound like phone callers. VideoSDK's IoT SDK exposes both G.711 flavours, AUDIO_CODEC_PCMA (A-law) and AUDIO_CODEC_PCMU (u-law), alongside AUDIO_CODEC_OPUS. For bridging calls to phone numbers, see VideoSDK telephony.
Use Opus everywhere you can, and expect G.711 only on legs that cross into telephony.
Hardware acceleration and battery
Hardware video decoders use less than 9% of the energy software decoders need, according to a 2024 review by Kr√§nzler, Herglotz, and Kaup.
That review, presented at the Picture Coding Symposium 2024, compared the energy efficiency of software and hardware video decoders. The size of the gap explains a detail in VideoSDK's codec table: AV1 is rated high on CPU, with the qualification that hardware acceleration can significantly reduce CPU usage. The codec is the same either way. Whether a dedicated chip does the work decides the cost.
Which devices have codec hardware
- H.264 on Apple devices. MDN notes that H.264 can be encoded and decoded in hardware on iOS and iPadOS. VP8 has no hardware support there, which increases processor load and reduces battery life.
- AV1 on phones. The Meta, Vodafone, and YouTube white paper (September 2025) reports AV1 hardware decode on most modern high-end phone chips, with limited support in mid and low tiers. Software decoding with the open-source dav1d decoder fills the gap at a modest cost in CPU use and battery.
- AV1 on iPhone. Apple added a dedicated AV1 decoder to the A17 Pro chip in the iPhone 15 Pro, announced September 12, 2023.
Why calls are harder than streaming
Most published codec battery data is about playback, where a server encodes and the phone only decodes. A video call reverses half of that: the phone encodes its own camera live, for the whole call. Apple's A17 Pro announcement describes an AV1 decoder, and decode hardware helps a phone receive AV1, not send it.
Before you make AV1 the sending codec on mobile, check that the device can encode it efficiently, not just play it. Browsers can tell you: navigator.mediaCapabilities.encodingInfo() accepts a configuration with type: "webrtc" and returns supported, smooth, and powerEfficient flags. A powerEfficient value of false is a hint that the device will encode that codec in software.
For battery-sensitive mobile audiences, H.264 on iOS and VP8 or H.264 elsewhere remain the safe sending codecs until you have tested AV1 encoding on the devices your users actually carry.
Video codec glossary
Video codec: Software or hardware that compresses video into a bitstream and decompresses it for display. VideoSDK supports four codecs for video on its camera track: VP8, H.264, VP9, and AV1.
Video coding format: The standardized bitstream a codec produces, independent of any implementation. H.264 is a coding format; x264 and OpenH264 are encoders for it.
Simulcast: Sending the same video at several resolutions at once, so a media server can forward each receiver the layer their bandwidth supports. In VideoSDK this is multiStream, which sends 720p, 360p, and 180p layers from a 720p camera.Codec negotiation: The exchange in which WebRTC endpoints agree on a codec both support before media flows. RFC 7742 guarantees that VP8 and H.264 are always available to agree on in browsers.
Codec fallback: Switching to a codec every participant supports when the chosen one fails. VideoSDK falls back to VP8 and reports the switch through the codec-changed event.Key takeaways on video codecs
- A video codec compresses raw video by two orders of magnitude: 331.8 Mbit/s of raw 720p becomes 1,500 kbps at VideoSDK's default 720p profile, about 221:1.
- A codec, a container, and an encoder are different things: H.264 is a codec, MP4 is a container, and x264 is an encoder.
- VP8 and H.264 remain the right default for live group calls, because both are mandatory in WebRTC browsers and both keep simulcast in VideoSDK's JavaScript SDK.
- VP9 and AV1 compress better, with AV1 up to 30% ahead of VP9, but VideoSDK runs them single-stream, and AV1 needs testing on Safari and iPhone.
- VideoSDK falls back to VP8 automatically when a device cannot send or receive the chosen codec, and the
codec-changedevent tells you which participant caused the switch.
Conclusion
Choosing a video codec for a real-time app is less about which codec compresses best and more about which one every participant can encode, decode, and adapt. Start with VP8 or H.264, log codec-changed events in production, and move specific call types to VP9 or AV1 when your own data shows the devices can handle it.
To try the codec option, follow the VideoSDK JavaScript quickstart and sign up at VideoSDK with $20 free credit. Questions are welcome in the VideoSDK Discord.
Which codec are you running in production, and has a codec-changed event ever surprised you? Drop a comment.
Frequently asked questions
What is a video codec?
A video codec is software or hardware that compresses digital video into a compact bitstream for storage or transmission, and decompresses it for playback. The word combines coder and decoder. H.264, VP8, VP9, and AV1 are the video codecs used most in real-time communication, and VideoSDK supports all four on its camera track.
What is the codec?
The codec of a video is the compression format its picture was encoded with, and you can check it directly. For a file, tools such as MediaInfo or FFmpeg's ffprobe report the codec of each stream. In a live VideoSDK call, the codec you set on createCameraVideoTrack() applies until a fallback occurs, and the codec-changed event reports the new codec when one does.
Which video codec is better, VP8, VP9, or AV1?
AV1 compresses best, VP9 comes second, and VP8 is the most compatible and the cheapest on CPU. For live group calls VP8 usually wins overall, because in VideoSDK both VP9 and AV1 disable simulcast. For recorded video, or one-to-one calls on known modern hardware, AV1 or VP9 is the better choice.
Does VideoSDK support AV1?
Yes, VideoSDK supports AV1 in its JavaScript, React, and iOS SDKs, set through the codec option on createCameraVideoTrack(). AV1 runs single-stream, without simulcast, and VideoSDK's documentation warns that it failed in testing on some Safari versions on macOS and on mobile web on iPhone. If a participant cannot decode AV1, VideoSDK moves the meeting to VP8 automatically.

