1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Dev/test target, not shipped: a panic here IS the diagnostic (that is what an
// assertion is). The workspace's unwrap/expect/panic denials exist to keep them
// off the decoder's untrusted-input path, so they are relaxed for this file.
//! Loop-filter-off P pictures must reconstruct their trailing P_Skip span (#15).
//!
//! A slice that ends in a run of skipped macroblocks leaves that run pending as a
//! deferred span. Only `deblock` flushed it, and finalization calls `deblock`
//! only when the filter is on, so with `disable_deblocking_filter_idc == 1` the
//! span was never reconstructed: zero samples in the bottom macroblock row,
//! which later P pictures then copied forward. x264 also writes idc 1 by itself
//! when QP is low enough that the filter would do nothing, which is why the
//! issue saw the same failure at QP <= 15 with deblocking "on".
//!
//! The vector is x264 via ffmpeg 8.1, 128x32, six frames, IPPPPP, CAVLC:
//! `ffmpeg -f lavfi -i testsrc2=s=128x32:r=24:d=0.25 -c:v libx264 -qp 24 -g 48
//! -bf 0 -x264-params no-deblock=1:cabac=0 -bsf:v h264_mp4toannexb -f h264`.
//! The reference YUV is ffmpeg 8.1's decode. Before the fix, 5 of the 6 frames
//! differed in macroblock row 1 (two-sided gate: the vector provably
//! distinguishes).
use Decoder;
/// Decode `stream` and require it to match ffmpeg's decode byte-for-byte.
/// The issue's "deblocking ON, QP <= 15" case. Nothing asks for the filter to
/// be off here; x264 writes `disable_deblocking_filter_idc = 1` on every slice
/// by itself because at QP 12 alpha is 0 and the filter would be a no-op. So
/// the stream takes the same filter-off finalization path.
///
/// x264 via ffmpeg 8.1.2, 64x48, six frames, IPPPPP, High/CABAC, one slice:
/// `ffmpeg -f lavfi -i testsrc2=s=64x48:r=24:d=0.25 -c:v libx264 -qp 12 -g 48
/// -bf 0 -bsf:v h264_mp4toannexb -f h264`. Reference is ffmpeg 8.1.2's decode.
/// Before the fix, 5 of 6 frames differed (macroblock row 2).
/// Multi-slice P pictures (a second reporter hit #15 on a Constrained Baseline
/// stream with two slices per frame). Only the LAST slice's trailing skip run
/// was ever left pending -- an earlier slice's run is flushed when the next
/// slice starts -- so this gates that the fix is not single-slice-only.
///
/// x264 via ffmpeg 8.1.2, 64x48, six frames, IPPPPP, Baseline/CAVLC, two
/// slices per picture (first_mb 0 and 8), QP 12 (filter off on every slice):
/// `ffmpeg -f lavfi -i testsrc2=s=64x48:r=24:d=0.25 -c:v libx264 -profile:v
/// baseline -qp 12 -g 48 -bf 0 -x264-params slices=2 -bsf:v h264_mp4toannexb
/// -f h264`. Before the fix, 5 of 6 frames differed (macroblock row 2).