Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ v -cc msvc test .

They cover fixed-width and Exp-Golomb bit reading, truncated input behavior,
NAL headers, RBSP look-ahead, integer bit widths, and representative
High-profile SPS/PPS parsing used by the player.
High-profile SPS/PPS parsing used by the player. HRD buffering syntax tests cover
one, two, and the maximum 32 CPB entries, including alignment of the following
delay fields. Counts beyond 32 entries are rejected by an assertion.

CI also runs strict V3 with TinyCC on Linux, using a pinned compiler snapshot.
The regression samples cover custom SPS/PPS scaling lists and the default-list
Expand Down
4 changes: 3 additions & 1 deletion h264.v
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,13 @@ pub fn (mut b Bitstream) read_scaling_list(mut scaling_list []i32, size_of_scali

// read_hrd_parameters consumes HRD syntax at the current cursor into sps.hrd.
// Normally called by read_vui_parameters; it does not schedule decoder buffering.
// The coded count is one less than the number of entries and must be at most 31.
pub fn (mut sps SequenceParameterSet) read_hrd_parameters(mut b Bitstream) {
sps.hrd.cpb_cnt_minus1 = b.ue()
assert sps.hrd.cpb_cnt_minus1 < 32
sps.hrd.bit_rate_scale = b.u(4)
sps.hrd.cpb_size_scale = b.u(4)
for sched_sel_idx in 0 .. sps.hrd.cpb_cnt_minus1 {
for sched_sel_idx in 0 .. sps.hrd.cpb_cnt_minus1 + 1 {
sps.hrd.bit_rate_value_minus1[sched_sel_idx] = b.ue()
sps.hrd.cpb_size_value_minus1[sched_sel_idx] = b.ue()
sps.hrd.cbr_flag[sched_sel_idx] = b.u1()
Expand Down
32 changes: 32 additions & 0 deletions hrd_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Verifies HRD entry counts and the cursor position of following syntax fields.
module h264

import encoding.hex

fn test_hrd_reads_all_cpb_entries() {
// H.264 E.1.2 encodes count minus one. Fixtures contain 1, 2 and 32 CPBs,
// distinct entry values, four delay widths, and an 0xa5 cursor sentinel.
for count, encoded in {
1: '9a30208a63a294'
2: '468c08220102531d14a0'
32: '04068c08220102507e303e9c1e8403c89076140ea2c1c860388d06e1c0da3c1a8200d2110660903284c188280c21505e0b02e85c168300b2190560d02a86c148380a21d04e0f02687c1281002482104604408a531d14a0'
} {
mut stream := Bitstream{}
stream.init(hex.decode(encoded)!)
mut sps := SequenceParameterSet{}
sps.read_hrd_parameters(mut stream)
assert sps.hrd.cpb_cnt_minus1 == u32(count - 1)
assert sps.hrd.bit_rate_scale == 3
assert sps.hrd.cpb_size_scale == 4
for i in 0 .. count {
assert sps.hrd.bit_rate_value_minus1[i] == u32(i + 2)
assert sps.hrd.cpb_size_value_minus1[i] == u32(64 - i)
assert sps.hrd.cbr_flag[i] == u32(i % 2)
}
assert sps.hrd.initial_cpb_removal_delay_length_minus1 == 5
assert sps.hrd.cpb_removal_delay_length_minus1 == 6
assert sps.hrd.dpb_output_delay_length_minus1 == 7
assert sps.hrd.time_offset_length == 8
assert stream.u(8) == 0xa5
}
}