# VP9 error-resilience list `vp9_err_v1`

Clean streams + one error per case; apply with `tools/err_apply.py`, run a decoder over the list with `tools/err_run.py`.
Bit 0 = MSB of the byte. `region`: header = uncompressed header fields, the bool-coded compressed header (one span, no fields), tile size markers, superframe index; payload = tile data; container (not sampled) = IVF. Errors are meant for the stream after decryption.

Usage: `python3 tools/err_run.py --list errors/vp9_err_v1.csv --cmd "mydec {in} {out}" --label mydec`; the result CSV has the same `id` as the list. Without `--cmd` the reference decoder is used (vpxdec).

**Decoder output.** `{out}` must receive raw planar 4:2:0 frames in display order, exactly one frame size per frame (8-bit samples, or 16-bit little-endian samples for 10-bit streams; odd sizes round the chroma planes up). A decoder that writes to stdout is used without `{out}` in the template. Frames are compared by md5 with the clean decode.

**Outcomes.** `CRASH` = killed by a signal other than SIGABRT (segfault, bus error...); `ABORT` = SIGABRT (assert / abort() on bad data - HM and JM do this); `TIMEOUT` = slower than max(--timeout, 4x the clean decode) and killed; `ERROR` = exit code != 0; `DECODED` = exit 0, with frames_mismatch / first_bad_frame / recovered_at (output index from which all frames equal the clean tail) / frames_missing. A crash inside a wrapper script shows up as ERROR with exit code 128+N. `ref_hang_confirmed` = the reference decoder still hung with a 600 s limit. Decoders run with an 8 GB address-space limit (ERR_DEC_MEM_GB): a decoder that tries to allocate more on a damaged header fails (ERROR / ABORT / CRASH) instead of exhausting the machine.

**Notes.** A payload `drop` removes a whole frame including its header (`part` = obu), or a whole IVF frame (`part` = tu). `truncate` usually decodes with frames missing. Header bits the reference trace does not name are labelled `unknown:after=<previous field>`. `damaged_symbol`: first differing symbol of the vpxdec tile trace (name, value, superblock, tile), in decode order; the trace's per-SB-row file reopen was fixed in a separate vpxdec build.

**2000 cases**

| stream | header | payload |
|---|---|---|
| `ERR/VP9/ERR_BoxingPractice/ERR_BoxingPractice_5120x1024_59p94p_10b_P2_vbr10M_L5.1_buf46M_10.35Mbps.ivf` | 250 | 250 |
| `ERR/VP9/ERR_Crosswalk/ERR_Crosswalk_5120x1024_59p94p_10b_P2_vbr10M_L5.1_buf46M_10.12Mbps.ivf` | 250 | 250 |
| `ERR/VP9/ERR_Long/ERR_Long_854x480_60p_10b_P2_vbr2.5M_L3.1_buf10M_2.52Mbps.ivf` | 250 | 250 |
| `ERR/VP9/ERR_LongResize/ERR_LongResize_854x480-resize_60p_10b_P2_vbr2.5M_L3.1_buf10M_2.91Mbps.ivf` | 250 | 250 |

| kind | cases |
|---|---|
| bitflip | 1500 |
| burst | 200 |
| truncate | 200 |
| drop | 100 |

Reference decoder (vpxdec) outcomes:

| outcome | cases |
|---|---|
| ERROR | 1439 |
| DECODED | 561 |
