HomeVideoGuides

🔬 In-depth guide

Why Video Re-encoding Loses Quality (and When It Doesn't)

Some video edits are free and some cost quality every time. What re-encoding does to the frames, and how to tell which kind of edit you are about to make.

“Re-encoding loses quality” is one of those statements that is true often enough to repeat and vague enough to be useless. It leads people to avoid edits that cost nothing, and to casually make edits that cost a lot.

The distinction that actually matters is not what the edit is called. It is whether the compressed frames inside the file have to be decoded and re-compressed, or whether they can be carried across untouched.

What is inside a video file

A video file is a container (MP4, MKV, WebM, MOV) holding one or more encoded streams plus an index that says which packet belongs at which timestamp. The container is metadata and packaging. The stream is where all the data is.

Inside the video stream, the frames are not stored as pictures. They are stored as three kinds of thing:

A group starting with a keyframe and running until the next one is a GOP. Typical encoder settings place a keyframe every one to ten seconds. Everything between them exists only as a chain of differences, which is why you cannot pull a single frame out of the middle of a GOP without decoding the frames before it.

This structure is the reason two superficially similar operations have completely different costs.

The two lossy steps, and why they compound

Every lossy video codec, whether H.264, VP9 or AV1, does roughly this to each block of pixels:

  1. Predict the block from neighbouring pixels or from another frame.
  2. Transform the prediction error into frequency coefficients.
  3. Quantise those coefficients, which means dividing them and throwing away the remainder.
  4. Entropy-code what is left.

Step 3 is the only lossy step, and it is irreversible. Everything else is exact arithmetic.

Now consider what happens when you re-encode. The decoder reconstructs approximate pixels from the already-quantised coefficients. The new encoder receives those pixels as if they were the truth. It has no way of knowing that a faint ringing halo around a hard edge is an artifact rather than real detail, so it dutifully spends bits describing the halo, and then quantises the whole thing again with its own rounding.

Generation loss across three encodesThree boxes left to right labelled first encode, second encode and third encode, joined by arrows. Under each box a bar of increasing width represents accumulated error.camera encodecompressre-compresserrorerror + errorand again
Each lossy pass quantises a picture that already contains the previous pass’s rounding, so the error accumulates rather than being re-measured from the original.

That is generation loss, and it is why a clip that has been through three messaging apps looks like it was filmed through a net curtain. Each app re-encoded, usually at a modest quality target, on top of the previous app’s output.

Edits that are genuinely free

An edit is free when the compressed packets can be copied across unchanged. In FFmpeg terms this is -c copy, stream copy, sometimes called remuxing.

Changing container without changing codec. Moving H.264 video and AAC audio from a MOV into an MP4 rewrites the packaging and touches none of the frames. The output is a different file with identical picture data.

Trimming on keyframe boundaries. This is the important one, because trimming is the single most common video edit. This site’s video trimmer seeks on the input side, before the decoder, and then stream-copies: the cut jumps to the nearest keyframe at or before your start time and copies packets from there. Your frames are bit-for-bit the ones from the source.

The trade-off is precision. If your requested start lands mid-GOP, the clip begins at the preceding keyframe instead, so you may get up to a keyframe interval of extra footage at the front. That is the honest price of a lossless cut. A frame-accurate cut requires decoding and re-encoding at least the leading GOP, which means accepting a lossy pass in exchange for exactness.

Metadata and container flags. Titles, language tags, and the rotation flag that tells a player to display a phone video upright are all container-level. Setting them costs nothing.

Edits that always re-encode

Any change of codec. Converting MP4 to WebM means H.264 or HEVC frames going in and VP8, VP9 or AV1 frames coming out. There is no shortcut between two different codecs’ internal representations, so this is a full decode and re-encode.

Any change of pixels. Resizing, cropping, rotating the actual image rather than the flag, changing frame rate, colour adjustment, watermarking, adding subtitles as burned-in pixels. All of these require the decoded picture, so all of them re-encode. Resizing a video for a specific aspect ratio is in this category.

Compression. Obviously, but worth stating: making a file smaller is re-encoding at a coarser quantisation. That is the whole mechanism.

Making the unavoidable pass cost as little as possible

When you do have to re-encode, most of the outcome comes down to one choice.

Bitrate-targeted encoding tells the encoder how many bits per second it may use, and it must fit the content into that budget however hard the content is. Quality-targeted encoding (CRF) inverts the arrangement: you specify how much loss you will accept and the encoder spends whatever bitrate that requires, cheaply on a static shot and generously on a fast pan.

For a single re-encode of already-compressed material, CRF is almost always the better choice, because your source is not uniformly demanding and a fixed bitrate will either starve the hard scenes or waste bits on the easy ones.

The video compressor here uses CRF values of 26 for its balanced preset and 28, 30 and 32 for its progressively smaller email, WhatsApp and Discord presets. Two things about those numbers are worth borrowing even if you never use the tool. First, FFmpeg’s own H.264 guidance notes that a change of about 6 in CRF roughly halves or doubles the resulting file size, which is why every gap between those four presets is exactly 2 rather than ten: a step of 2 is a third of the way to halving the file, a noticeable but survivable change, while a jump of ten would take you past a halving in a single move. Second, the smaller presets also cap resolution (1280 pixels on the longest side, 854 for the smallest preset), because past a certain point reducing resolution preserves more perceived quality than pushing quantisation further on a full-size frame. A clean 720p picture reads as better than a mushy 1080p one at the same file size.

Two more details that quietly cost quality on every pass:

Chroma subsampling. Most delivery encodes, including the ones here, force 4:2:0, which stores one pair of colour samples for each 2x2 block of brightness samples. The cost of that depends on what you started from: a 4:4:4 source carries a colour pair for every single brightness sample, so four pairs per 2x2 block become one and three quarters of the colour samples go on the first pass, while a 4:2:2 source is already halved horizontally and loses half, because only the vertical dimension is decimated further. Either way it never comes back, and it is most visible on saturated red edges and on text.

Audio. The audio stream is a separate lossy encode and it re-encodes under exactly the same rules. Compressing a clip to AAC at 96 kbps when the source was already a lossy 128 kbps track is a second generation on the sound as well as the picture.

A practical checklist

Before any video edit, ask what it needs. If it only touches packaging or timing at keyframe boundaries, insist on a tool that stream-copies. If it touches pixels, accept one re-encode, do all your pixel changes in that single pass rather than in three separate saves, and pick your quality target deliberately.

It also helps to know what you actually have before deciding. A video info viewer will tell you the codec, resolution, frame rate and bitrate of a file, which is often enough to reveal that the “4K” clip someone sent you is an upscaled 1080p encode at a bitrate too low to justify either number.

One last note specific to doing this in a browser. The encoder on this site is FFmpeg compiled to WebAssembly, running in your tab, deliberately single-threaded (the multi-threaded build requires HTTP headers that break other things on the page). That means encoding is honest but slow: nothing is uploaded anywhere, and a long clip will take real time on your own CPU. For a quick trim that is irrelevant, because a stream copy barely has to do any work at all. For a full re-encode of a ten-minute 1080p file, it is the main thing you will notice.

The tools in this guide, in action

Screenshot of the Trim Video tool with sysfenix-sample.webm (183 KB) loaded, Start time (seconds) set to 0, End time in seconds, where 0 means the end of the video set to 0
Trim Video mid-process: sysfenix-sample.webm (183 KB) loaded, Start time (seconds) set to 0, End time in seconds, where 0 means the end of the video set to 0.
Screenshot of the Video Info Viewer tool with sysfenix-sample.webm (186 KB) loaded
Video Info Viewer mid-process: sysfenix-sample.webm (186 KB) loaded.

Frequently asked questions

Does trimming a video reduce its quality?

Not if the tool copies the streams instead of re-encoding them. A stream-copy trim rewrites the container around the existing compressed frames, so the pixels are bit-for-bit identical to the source. The trade-off is that the cut can only land on a keyframe, so the start of your clip may include up to a couple of seconds you asked to remove.

How many times can I re-encode a video before it looks bad?

There is no fixed number, because it depends on the codec, the quality setting and the content. What is predictable is the direction: every lossy pass adds error to the error already in the file, and the encoder cannot tell the difference between real detail and the previous encoder's artifacts, so it spends bits preserving those artifacts. Two careful passes at a high quality are usually fine. Six passes through messaging apps are not.

Is converting MP4 to WebM lossless?

No. MP4 and WebM use different video codecs, so the frames must be fully decoded and re-encoded. Only a change of container that keeps the same codecs can be lossless, and MP4 to WebM is not that.

What is CRF and why is a higher number worse?

CRF stands for Constant Rate Factor. Rather than targeting a bitrate, you tell the encoder how much quality loss you will tolerate and it spends whatever bits that needs, frame by frame. The scale runs from 0 (lossless) to 51 (terrible), so a higher number means coarser quantisation, a smaller file and more visible damage.

Why is in-browser video encoding so slow?

Because it is real encoding, not a server upload. The encoder here is FFmpeg compiled to WebAssembly and running in your own tab, and it runs single-threaded, so it cannot spread the work across your CPU cores the way a native desktop encoder does. Nothing is uploaded, which is the point, but a long clip genuinely takes a while.

Tools mentioned in this guide