DEV Community

Cover image for A Codec-First Workflow for Debugging Pixelated Video
Tover Wu
Tover Wu

Posted on

A Codec-First Workflow for Debugging Pixelated Video

“The video looks pixelated” is not a diagnosis. It is a symptom that can be introduced at four different stages:

  1. the camera or screen recorder captured too little detail;
  2. an editor exported an undersized or over-compressed file;
  3. a messaging or video platform created a lower-quality rendition; or
  4. the player selected a low-quality stream while the master remained intact.

Those cases need different fixes. Upscaling a clean master because a browser showed a temporary 360p rendition creates more work and another lossy generation. Raising the export resolution on an already damaged source only produces larger blocks.

This tutorial builds a repeatable, codec-first workflow for locating the first bad generation before changing anything.

1. Preserve every generation

Start with copies, not edits. Keep these files when they exist:

01-camera-or-screen-recording.mp4
02-editor-export.mp4
03-uploaded-or-shared-download.mp4
04-player-capture-for-reference-only.mp4
Enter fullscreen mode Exit fullscreen mode

Do not overwrite the earliest file. A downloaded social-media copy may have a smaller frame, lower bitrate, different frame rate, and a second or third round of compression. Treat it as evidence, not as the new master.

If you have only one file, record where it came from. “Saved from Messages” is useful provenance. “video-final-final2.mp4” is not.

2. Probe the files before watching them

Use ffprobe to collect the stream and container facts that a file browser usually hides:

ffprobe -v error \
  -select_streams v:0 \
  -show_entries stream=codec_name,profile,width,height,pix_fmt,avg_frame_rate,r_frame_rate,bit_rate \
  -show_entries format=duration,size,bit_rate,format_name \
  -of json \
  01-camera-or-screen-recording.mp4
Enter fullscreen mode Exit fullscreen mode

Run the same command for every generation. Save each JSON result next to its video.

The useful questions are comparative:

Signal What a change can indicate
Width × height fell A smaller rendition or export was created
Frame rate changed Frames may have been dropped or duplicated
Overall bitrate collapsed Stronger compression probably entered here
Codec changed The file was transcoded, even if the dimensions match
Duration changed Trimming, variable-frame-rate handling, or a bad remux may have occurred
Pixel format changed Chroma or bit-depth information may have been reduced

Bitrate is not a universal quality score. A static slide and handheld night footage do not require the same number of bits. It is still a strong clue when two generations contain the same scene and one has a dramatic bitrate drop.

3. Normalize the comparison

Comparing two players side by side is surprisingly unreliable. They may use different scaling, color management, hardware decoding, or playback quality.

Extract frames at the same timestamp instead:

mkdir -p frames

ffmpeg -ss 00:00:07.500 \
  -i 01-camera-or-screen-recording.mp4 \
  -frames:v 1 -vsync 0 frames/source-007500.png

ffmpeg -ss 00:00:07.500 \
  -i 02-editor-export.mp4 \
  -frames:v 1 -vsync 0 frames/export-007500.png
Enter fullscreen mode Exit fullscreen mode

Choose at least three scene types:

  • a still or slow section with fine texture;
  • a fast-motion section;
  • a dark or noisy section.

Compression failures often hide in a paused bright frame and become obvious during motion. A single attractive thumbnail is weak evidence.

When the dimensions differ, scale both extracted frames to the same display size for visual inspection, but keep the originals too. Scaling is part of the experiment and should not be confused with recovered detail.

4. Locate the first bad generation

Use the earliest pair where the symptom changes.

The camera file is already blocky

The loss occurred at capture or before you received the file. Look for low recording bitrate, digital zoom, poor light, sensor noise, an undersized screen recording, or a file that was already downloaded from another platform.

A clean re-export cannot restore discarded camera detail. Restoration or enhancement may reduce visible block boundaries and create a more usable enlargement, but it cannot reconstruct the exact texture that was never recorded.

The camera file is clean but the editor export is blocky

The export path is the best place to fix the problem. Check:

  • whether the timeline resolution matches the intended output;
  • whether the export accidentally used a low-bitrate preset;
  • whether frame-rate conversion introduced duplicates or cadence problems;
  • whether a proxy or preview file was exported instead of the original media; and
  • whether the file was encoded twice.

Re-export once from the clean source. Avoid passing the damaged export through another encoder.

The local export is clean but the uploaded version is blocky

Do not repair the clean local file. Wait for the platform’s higher-quality renditions, select the intended playback quality, and compare the exact same moment again.

If a downloaded platform copy is smaller or has a much lower bitrate than the local export, that difference is expected evidence of a delivery transcode—not proof that the master needs upscaling.

Only the editor preview is blocky

Many editors lower preview quality to keep playback responsive. Render a short test segment and inspect the saved file outside the editor before changing the project or source.

5. Use objective metrics carefully

If two files are frame-aligned and represent the same image sequence, SSIM can help detect a change:

ffmpeg \
  -i 01-camera-or-screen-recording.mp4 \
  -i 02-editor-export.mp4 \
  -lavfi "[0:v]setpts=PTS-STARTPTS[ref]; \
           [1:v]setpts=PTS-STARTPTS[dist]; \
           [ref][dist]ssim=stats_file=ssim.log" \
  -f null -
Enter fullscreen mode Exit fullscreen mode

This only makes sense when the inputs are aligned. A crop, a one-frame offset, a color-range difference, or a frame-rate conversion can dominate the score.

Also, a higher SSIM value does not guarantee that one version looks better. Sharpening may create halos; denoising may erase skin texture; AI enhancement may generate plausible but incorrect detail. Use metrics to support a controlled visual comparison, not to replace it.

6. Test the smallest useful segment

Once you know where the damage began, make a short, lossless-trimmed test when the container and keyframes permit it:

ffmpeg -ss 00:00:05 -i damaged-source.mp4 \
  -t 00:00:08 -c copy diagnostic-sample.mp4
Enter fullscreen mode Exit fullscreen mode

If stream copying starts at the wrong visual point because of keyframe placement, create a short controlled transcode and document the settings instead:

ffmpeg -ss 00:00:05 -i damaged-source.mp4 \
  -t 00:00:08 \
  -c:v libx264 -crf 16 -preset slow \
  -c:a aac -b:a 192k \
  diagnostic-sample.mp4
Enter fullscreen mode Exit fullscreen mode

Run any restoration, denoise, or upscale experiment on that segment first. Compare moving footage at the final display size. Look specifically for:

  • blocks that became smoothed but not truly detailed;
  • ringing around high-contrast edges;
  • unstable texture between frames;
  • waxy faces or foliage;
  • altered text, logos, or UI elements; and
  • a file-size increase without a visible benefit.

Only process the full video after the short test survives those checks.

A compact decision table

Earliest bad version Best first action
Camera/original Preserve it; test realistic cleanup on a short segment
Editor export Re-export once from the clean source with suitable settings
Shared/downloaded copy Transfer the original instead of repairing the copy
Platform rendition Wait for processing and verify playback quality
Editor preview only Judge a saved test export outside the editor

The main idea is simple: fix the stage that introduced the loss. Resolution alone is not quality, and another encode is not automatically a repair.

Disclosure and further example

I work on PixelatedFix, so I have a commercial interest in this problem. I wrote this workflow to put source and export diagnosis before product use. If the earliest remaining file is genuinely compressed or low-resolution, the PixelatedFix pixelated-video guide shows the same “find the first bad generation” decision with visual examples and states the limits of enhancement. If a clean original still exists, use that instead.

The best result is often not a smarter upscaler. It is finding the clean file one generation earlier.

Top comments (0)