A preview is decoded and re-encoded at every pipeline stage; why does quality keep dropping at a fixed quality setting?
answer
- the setting is relative, not absolute
- each pass sees the previous pass's output
- errors add, they do not cancel
- artifacts get coded as real detail
- mismatch between passes drives the decline
basics
~20 sA quality setting bounds distortion against the encoder's own input, not against the original. Each pass starts from an already damaged copy, so new error is added to old error rather than measured against the truth, and the errors add instead of cancelling.
solid answer
~50 sThe setting is **relative**. Pass two promises to stay close to what pass one produced, and pass one's output already carries error. So the distortions stack: the second pass's error is added to a signal that is no longer the original, and independent-looking errors from successive passes tend to add rather than cancel. It is usually worse than a simple sum, because the first pass's artifacts look like real high-frequency detail to the second encoder, which spends bits preserving them — sometimes producing a *larger* file that is *further* from the original. The honest caveat: if the encoder, its settings and the geometry are identical and nothing edits the image in between, output can converge to a near fixed point after a pass or two. What keeps the decline going is mismatch between passes — a crop, a resize, a different setting, a different grid.
go deeper
Hold on to one fact: the quality setting measures distance from whatever the encoder was handed, so repeated encoding drifts away from the original even when the number never changes.
Explain the mechanics: uncorrelated errors from successive passes add in squared error, and the previous pass's artifacts look like real detail to the next encoder, which spends bits preserving them.
Show how you would find and remove the extra hops in a real pipeline — compose transforms and encode once from the master, and make the number of encodes between archive and viewer observable.
The trade-off is storing high-fidelity masters and regenerating on demand versus caching derived artifacts; the cost of the second is compounding damage and a library whose worst copy has quietly become the source.
## What a quality setting actually bounds A lossy encoder is given samples and a fidelity target, and it produces a description whose reconstruction stays within some **distortion** of *the samples it was handed*. Nothing in the encoder refers to an original it never saw. That is the whole mechanism behind generation loss: fidelity is measured against the **immediate input**, and after the first encode the immediate input is no longer the truth. Write it as a chain. Let `x` be the original, `x1` the decode of the first encode, `x2` the decode of a re-encode of `x1`. The setting bounds `d(x1, x)` on the first pass and `d(x2, x1)` on the second. What a viewer sees is `d(x2, x)`, which nothing in the pipeline ever measured or constrained. ## Why the errors add rather than cancel The second pass has no way to distinguish the first pass's damage from real signal, so it treats the artifacts as content to preserve: - The two passes' errors are driven by different decisions and are close to **uncorrelated**, and uncorrelated errors combine in squared error by **adding**, not by averaging out. Total squared error grows with the number of passes rather than settling. - **Artifacts cost bits.** Ringing at edges and blocky discontinuities are high-frequency structure. An encoder asked for high fidelity spends real rate preserving them, which is why a re-encode can be bigger than its input while being further from the original. - **Any geometric change resets the grid.** A crop, a resize, a rotation or a different internal block alignment means the second pass quantises a *differently decomposed* signal, so its error lands in new places instead of repeating the first pass's decisions. ## The honest caveat: when it stops getting worse "Re-encoding always degrades" is too strong, and an interviewer will push on it. If **the same encoder, the same settings and the same geometry** are applied with no intervening edit, many designs settle quickly: the second pass is being asked to reproduce a signal that already lies close to what that encoder can represent, so it changes little, and further passes change less. The decline in real pipelines is driven by **mismatch** — a different stage uses a different setting, a thumbnail service resizes, a crop shifts the alignment, a watermark is composited in. Each mismatch is a fresh, independent quantisation of the accumulated result. | Pipeline shape | Passes over the same bytes | Outcome | |---|---|---| | Derive every variant from the master in one encode | 1 | Only the intended distortion; the original stays available | | Re-encode with identical settings and geometry | n, no change between | Settles near a fixed point after a pass or two | | Re-encode after a crop, resize or setting change | n, mismatched | Error accumulates on every pass, visibly | | Round-trip through an intermediate stage each time | n per hop | Worst case: accumulation plus bits spent on artifacts | ## What this means for a delivery tier The fix is structural, not a matter of turning the quality up: 1. **Keep a high-fidelity master** and treat everything served as disposable output regenerated from it. 2. **Compose the transforms, then encode once.** Crop, resize and watermark in the decoded domain, and let exactly one encode happen at the end of the chain. 3. **Never promote a delivery artifact to master.** The moment a downstream stage's input is a previously delivered file, the chain has grown a hop nobody planned for. 4. **Make the hop count observable.** Stages that silently decode and re-encode are the ones that surprise people; the count of encodes between the archive and the viewer is the number worth knowing. ## The reasoning trap to avoid The intuitive model — "quality 80 means the output is at quality 80" — treats the setting as an absolute floor. It is not. It describes a **distance from whatever arrived**, so a chain of three stages each promising "close enough" can deliver something none of them would have accepted as output. This is also why comparing a stage's output against the *previous* stage, which is the easy comparison to automate, cannot detect the problem: every hop passes its own check while the chain fails. The only comparison that means anything is against the master, and the only way to keep that cheap is to keep the master.
- When does repeated re-encoding stop making things worse?When nothing changes between passes. With the identical encoder, identical settings and identical geometry, and no edit in between, the input already sits close to what that encoder represents, so successive outputs converge to a near fixed point. Degradation in practice comes from mismatch: a crop, a resize, a different setting or a different alignment makes each pass a fresh, independent quantisation.
- Why can a re-encode produce a larger file than its input?Because the previous pass's artifacts — ringing at edges, blocky discontinuities — are high-frequency structure, and the encoder cannot tell them from real detail. Asked for high fidelity, it spends rate preserving them. You get more bytes that are further from the original, which is the clearest sign that the pipeline is re-encoding where it should be re-deriving.
- A stage compares its output against its own input and reports no regression. What is wrong with that check?It measures the wrong distance. Every hop can pass a comparison against its immediate input while the chain drifts steadily away from the original, because nothing in the chain ever measures against the original. Compare against the retained master, or count the encodes between master and viewer and drive that number to one.
saying these in an interview costs you the question
- Believes a fixed quality setting means fixed quality against the original.
- Thinks the second encode's distortion is measured against the original.
- Expects re-encoding to be idempotent even after a crop or resize.
- Assumes a bigger output file means the quality improved.
- Promotes each stage's output to the input of the next stage.
- Validates a hop by comparing it only against the previous hop.