DEV Community

Peiguan
Peiguan

Posted on

Is a 4K Bama Bound AI Video Really Sharper? Measuring a Clip's Effective Resolution With an ffmpeg Round-Trip Test

Written November 4, 2026 (CST, UTC+8). I build bamabound.app, the one-photo generator for the "I'M BAMA BOUND" banner meme. I didn't run any paid generations for this post. Every number below comes from synthetic test clips made on my machine, and the script is there so you can run it on your own downloads.

As of today, bamabound.app offers four resolutions for the same 8-second vertical clip. The pricing page lists 480p at $7.99 (1 credit), 720p at $9.99 (2 credits), 1080p at $14.99 (4 credits) and 4k at $24.99 (7 credits). 480p is the default. So people ask a fair question, and they ask it about every AI video tool: if I pay for 4K, do I get 4K worth of detail, or just a bigger file?

The pixel count can't tell you. ffprobe will say 2160x3840 for a real 4K picture and for a 720p picture that was stretched to 4K on export. What you need is the effective resolution: the smallest size the picture could be stored at without losing anything visible.

The round-trip test

The idea is simple:

  1. Shrink each frame to a candidate size, say 480 pixels wide.
  2. Scale it back up to the original size.
  3. Compare with the original (PSNR).

If the picture never held more than 480 pixels' worth of detail, shrinking it loses almost nothing, and the round trip comes back nearly identical (high PSNR). If the picture has real fine detail, shrinking throws that away and PSNR drops. The smallest candidate that still round-trips cleanly is the effective resolution.

ffmpeg does all three steps in one filter graph: split, scale down, scale back up, and its psnr filter compares the result with the untouched copy. Python just loops over candidates and reads the number.

#!/usr/bin/env python3
"""eff_res.py: estimate the *effective* resolution of a video, not just its pixel size.

Idea: shrink each frame to a candidate width, scale it back up, and compare with
the original (PSNR, ffmpeg's psnr filter). If the picture never had more detail
than that width, the round trip loses almost nothing. The smallest width that
still round-trips cleanly is the effective resolution.

Usage: python3 eff_res.py clip.mp4 [--seconds 4] [--clean 42]
"""
import argparse, json, re, subprocess, sys

CANDIDATES = [480, 720, 1080, 1440, 2160]  # short side ("p") for a vertical clip


def probe(path):
    out = subprocess.run(["ffprobe", "-v", "error", "-select_streams", "v:0",
                          "-show_entries", "stream=width,height", "-of", "json", path],
                         capture_output=True, text=True, check=True).stdout
    s = json.loads(out)["streams"][0]
    return s["width"], s["height"]


def roundtrip_psnr(path, w, h, short, seconds):
    # scale the short side to `short`, keep aspect, back to w x h, measure PSNR
    if w <= h:
        down = f"scale={short}:-2:flags=area"
    else:
        down = f"scale=-2:{short}:flags=area"
    graph = (f"[0:v]format=gray,split[a][b];"
             f"[b]{down},scale={w}:{h}:flags=lanczos[c];[a][c]psnr")
    err = subprocess.run(["ffmpeg", "-hide_banner", "-nostats", "-t", str(seconds),
                          "-i", path, "-lavfi", graph, "-f", "null", "-"],
                         capture_output=True, text=True).stderr
    m = re.search(r"PSNR .*?average:([\d.]+|inf)", err)
    if not m:
        sys.exit("psnr filter gave no result:\n" + err[-800:])
    return float("inf") if m.group(1) == "inf" else float(m.group(1))


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("clip")
    ap.add_argument("--seconds", type=float, default=4.0)
    ap.add_argument("--clean", type=float, default=42.0,
                    help="round-trip PSNR (dB) that counts as 'no detail lost'")
    a = ap.parse_args()
    w, h = probe(a.clip)
    native = min(w, h)
    cands = [c for c in CANDIDATES if c < native]
    rows = [(c, roundtrip_psnr(a.clip, w, h, c, a.seconds)) for c in cands]
    print(f"{a.clip}: {w}x{h} (labelled {native}p)")
    for c, p in rows:
        print(f"  via {c}p: PSNR {p:6.2f} dB")
    if not rows:
        print("  nothing smaller to test"); return
    clean = [c for c, p in rows if p >= a.clean]
    if not clean:
        print(f"  effective: ~{native}p (no smaller size round-trips above {a.clean} dB)")
    else:
        print(f"  effective: ~{min(clean)}p (smallest size that round-trips above {a.clean} dB)")


if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

A few choices worth explaining:

  • Grey only (format=gray). Chroma is already stored at half resolution in yuv420p, so it would blur the signal. Luma carries the detail you see.
  • area down, lanczos up. Area averaging is the honest way to shrink. Lanczos is a sharp upscaler, so a clean round trip really means "nothing was there", not "the upscaler was blurry too".
  • "p" means the short side. A vertical 1080p clip is 1080 pixels wide, so candidates scale the width.
  • First 4 seconds by default. That's half of an 8-second clip, and it keeps a 4K run fast. Use --seconds 8 for the whole thing.

Testing it on clips where I know the answer

To check that it works, I need clips whose true detail I know. This script makes three 1080×1920 clips from the same busy test pattern (ffmpeg's testsrc2 plus a little noise). One really has 1080p detail. The other two were shrunk to 480 and 720 wide and then stretched back to 1080×1920 with bicubic scaling, which is what a careless export does.

#!/bin/sh
# Synthetic 1080x1920 test clips: one with real 1080p detail, two upscaled from smaller sizes.
set -e
SRC="testsrc2=size=1080x1920:rate=30,noise=alls=10:allf=t"
ffmpeg -v error -y -f lavfi -i "$SRC" -t 4 -c:v libx264 -crf 16 -pix_fmt yuv420p native1080.mp4
ffmpeg -v error -y -f lavfi -i "$SRC" -t 4 -vf "scale=480:854:flags=area,scale=1080:1920:flags=bicubic" \
  -c:v libx264 -crf 16 -pix_fmt yuv420p up_from_480.mp4
ffmpeg -v error -y -f lavfi -i "$SRC" -t 4 -vf "scale=720:1280:flags=area,scale=1080:1920:flags=bicubic" \
  -c:v libx264 -crf 16 -pix_fmt yuv420p up_from_720.mp4
Enter fullscreen mode Exit fullscreen mode

All three files report the same size to ffprobe. Here's what the script printed (ffmpeg 7.1, Debian):

native1080.mp4: 1080x1920 (labelled 1080p)
  via 480p: PSNR  30.41 dB
  via 720p: PSNR  32.06 dB
  effective: ~1080p (no smaller size round-trips above 42.0 dB)
up_from_480.mp4: 1080x1920 (labelled 1080p)
  via 480p: PSNR  45.36 dB
  via 720p: PSNR  48.76 dB
  effective: ~480p (smallest size that round-trips above 42.0 dB)
up_from_720.mp4: 1080x1920 (labelled 1080p)
  via 480p: PSNR  38.86 dB
  via 720p: PSNR  44.95 dB
  effective: ~720p (smallest size that round-trips above 42.0 dB)
Enter fullscreen mode Exit fullscreen mode

Three files, one label, three different answers, and each one is right. The real 1080p clip loses about 30 dB worth of detail when squeezed through 480 wide. The clip that was secretly 480p barely notices.

Then I re-encoded all three at CRF 28 (ffmpeg -i X.mp4 -c:v libx264 -crf 28 -preset veryfast q28_X.mp4), which is closer to what a social app does to an upload. Output condensed to one line per file:

q28_native1080.mp4:  via 480p 34.84 dB, via 720p 37.31 dB -> ~1080p
q28_up_from_480.mp4: via 480p 46.87 dB, via 720p 51.25 dB -> ~480p
q28_up_from_720.mp4: via 480p 41.85 dB, via 720p 47.73 dB -> ~720p
Enter fullscreen mode Exit fullscreen mode

Still right, but look at the 720p case: 41.85 dB through 480 wide, just under the 42 dB line. Heavy compression smooths fine detail away, so a heavily compressed clip starts to look "lower resolution" to this test. That's honest, because it's true of what you see, but it means the threshold isn't a law of nature. If you're near the line, look at the curve, not just the verdict.

How to read the result on a real clip

Run it on the file you downloaded, before any app re-compresses it:

python3 eff_res.py my_bama_bound_4k.mp4 --seconds 8
Enter fullscreen mode Exit fullscreen mode

What it measures is detail present in the picture, which is not quite the same as "was it upscaled". Three things lower the effective number without anyone cheating:

  • A soft source photo. The generator works from one photo of one adult (photo requirements). A blurry or small photo can't produce fine skin and fabric detail at any output size.
  • Smooth content. A sunny lawn and a flat red banner have big areas with little texture. A clip with less texture round-trips better at small sizes, so it's best to compare two resolutions of the same scene rather than judge one in isolation.
  • Motion blur. The banner moves, and blurred frames carry less detail. Averaging over all frames dilutes this, and --seconds lets you pick a calmer stretch.

So the useful experiment is: make the same photo at two resolutions, run both, and see whether the higher one's curve actually moves. If 4K round-trips cleanly through 1080, the extra pixels on your file aren't carrying extra detail for that clip.

Do you even need it?

For most people posting this meme, the honest answer comes before any measurement: where will it be watched? Most phone screens are somewhere around 1,080 to 1,440 physical pixels wide, and the app you post to will re-encode whatever you upload. The higher tiers matter when you'll crop or zoom, show it on a big screen, or pull still frames from it.

On bamabound.app, 480p is the default and the cheapest at $7.99 per clip, and the higher tiers are there for those cases (prices, FAQ). The clip itself is the same 8-second scene at every tier: one photo in, a words-only red banner that reads I'M BAMA BOUND, generated cheering, no prompt box. Higher tiers also spend more credits per clip if you're using a pack, so check the pricing table before you spend a pack on 4K.

Limits of this script

  • It needs ffmpeg/ffprobe on PATH and Python 3.8+. No other dependencies.
  • PSNR is a blunt measure. It's fine for "is the detail there", but it isn't a quality score.
  • The 42 dB threshold was tuned on these test clips. Treat it as a default, and use --clean to change it.
  • It tests candidate sizes 480, 720, 1080, 1440 and 2160. Odd sizes in between will round to the nearest one below.

If you try it on a clip and the result surprises you, I'd like to hear about it. The help page has the support address.

Top comments (0)