The Still-Frame Threshold Depends on Bit Depth
※本記事にはアフィリエイトリンクを含む場合があります。内容は広告の有無に影響されません。
結論
The YAVG threshold for detecting stills with tblend and signalstats scales with the luma range, so a threshold of 4.8 on 12-bit has to be read as 1.2 on 10-bit or the verdict changes entirely.
The short version
The YAVG threshold scales with the material’s bit depth.
Our measured values were these.
| Export | pix_fmt |
YAVG counted as still |
|---|---|---|
| ProRes 4444 | yuv422p12le (12-bit) |
4.8 |
| ProRes 422 HQ | 10-bit | 1.2 |
Exactly a factor of four apart. 12-bit luma runs 0–4095 and 10-bit runs 0–1023 — the range itself is about four times larger. For the same difference in the picture, a different bit depth changes the YAVG number by that same factor of four.
So applying 4.8, meant for 12-bit, to 10-bit material classifies moving frames as still. And applying 1.2, meant for 10-bit, to 12-bit makes still material read as moving.
What is actually happening
Detecting still frames, done plainly, looks like this.
- Build the difference between consecutive frames (
tblend’sdifference) - Read the mean brightness of that difference image (
signalstats’YAVG) - Treat stretches where the mean is below a threshold as “still”
The less difference there is, the blacker the difference image and the closer YAVG gets to 0. “How black is it” is standing in for “is it still”.
So YAVG is a luma value itself, not a ratio. Change the range and the number changes.
Check before you use it
Before applying a threshold, look at how many bits the material is.
ffprobe -v error -select_streams v:0 \
-show_entries stream=pix_fmt,codec_name \
-of default=nw=1 input.mov
codec_name=prores
pix_fmt=yuv422p12le
12le is 12-bit, 10le is 10-bit.
It changes even when you did not mean to change the export settings. Switching the codec preset from ProRes 4444 to 422 HQ alone drops the bit depth, so measuring with the threshold left as it was quietly breaks the verdict from that day onward.
No error appears. The numbers keep coming out. They keep coming out while meaning something different — that is what makes this kind of measurement dangerous.
Decide the threshold by measuring
Rather than reusing an inherited value, take the boundary on your own material.
- Pick a clearly still stretch and measure its YAVG
- Pick a clearly moving stretch and measure its YAVG
- Put the threshold between them
If the two values are too close, that material cannot be separated by YAVG. Rather than persisting with threshold tweaks, admitting it cannot be separated finishes sooner.
Split long videos
Push a long piece through in one go and you will not notice when the render dies partway.
Ours is four parts of 1080 frames each, each run in the foreground before being concatenated. The urge to send it to the background is strong, but moving on to the next step without noticing it died costs more.
Do not confuse numbers coming out with measuring
The most dangerous thing about this measurement is that the results come out perfectly normally even when the threshold is wrong.
An output of “0 stills” does not distinguish between there being no stills and the threshold being too loose to catch any. The same screen appears either way.
Checking pix_fmt every time is how a human keeps hold of that distinction.
よくある質問
Q1How do you detect still frames mechanically?
Build the difference between consecutive frames with tblend, then read the mean brightness of that with signalstats' YAVG. The less difference, the lower the YAVG, so a stretch below a threshold counts as still. The threshold depends on the material's bit depth — do not reuse a fixed value.
Q2How should the threshold be chosen?
By measuring. Ours were 4.8 at 12-bit (yuv422p12le) and 1.2 at 10-bit — a factor of four, almost exactly the ratio of the luma ranges. On new material, measure the YAVG of a clearly still stretch and a clearly moving one and take the boundary between them.
Q3How do I check my material's bit depth?
Look at pix_fmt with ffprobe. yuv422p12le is 12-bit, yuv422p10le is 10-bit. It can change when you switch a codec preset even if you did not mean to change the export settings, so checking before applying a threshold every time is the safe habit.
Q4Processing never finishes on a long video
Split by frame count, render, and concatenate. Ours is four parts of 1080 frames each. Sending it to the background means not noticing when it dies partway, so running it in the foreground and confirming completion finishes sooner overall.
この記事の根拠
- ドキュメントファイル 153〜157行目
本文の主張は、上の記録に書かれていることだけです。運用しているリポジトリは非公開のため リンクは張れませんが、どのファイルの何行目を、どのコミット時点で見て書いたかは 記事ごとに残しています。推測で書いた箇所はありません。