2024-05-02 12:12:13 +02:00
|
|
|
package avif
|
|
|
|
|
|
2024-05-03 01:42:45 +02:00
|
|
|
import "core:fmt"
|
2024-05-02 12:12:13 +02:00
|
|
|
import "core:io"
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
SELECT_SCREEN_CONTENT_TOOLS :: 2
|
|
|
|
|
SELECT_INTEGER_MV :: 2
|
|
|
|
|
MAX_OPERATING_POINTS :: 32
|
|
|
|
|
MAX_TILE_COLS :: 64
|
|
|
|
|
MAX_TILE_ROWS :: 64
|
|
|
|
|
NUM_REF_FRAMES :: 8
|
|
|
|
|
REFS_PER_FRAME :: 7
|
|
|
|
|
PRIMARY_REF_NONE :: 7
|
|
|
|
|
MAX_SEGMENTS :: 8
|
|
|
|
|
|
2024-05-02 12:12:13 +02:00
|
|
|
OBUType :: enum u8 {
|
|
|
|
|
SEQUENCE_HEADER = 1,
|
|
|
|
|
TEMPORAL_DELIMITER = 2,
|
|
|
|
|
FRAME_HEADER = 3,
|
|
|
|
|
TILE_GROUP = 4,
|
|
|
|
|
METADATA = 5,
|
|
|
|
|
FRAME = 6,
|
|
|
|
|
REDUNDANT_FRAME_HEADER = 7,
|
|
|
|
|
TILE_LIST = 8,
|
|
|
|
|
PADDING = 15,
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-03 01:42:45 +02:00
|
|
|
OBUError :: enum {
|
|
|
|
|
ReservedOBU,
|
2024-05-04 03:24:01 +02:00
|
|
|
ReservedSeqProfile,
|
2024-05-03 01:42:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ColorPrimaries :: enum u8 {
|
|
|
|
|
BT_709 = 1,
|
|
|
|
|
UNSPECIFIED = 2,
|
|
|
|
|
BT_470_M = 4,
|
|
|
|
|
BT_470_B_G = 5,
|
|
|
|
|
BT_601 = 6,
|
|
|
|
|
SMPTE_240 = 7,
|
|
|
|
|
GENERIC_FILM = 8,
|
|
|
|
|
BT_2020 = 9,
|
|
|
|
|
XYZ = 10,
|
|
|
|
|
SMPTE_431 = 11,
|
|
|
|
|
SMPTE_432 = 12,
|
|
|
|
|
EBU_3213 = 22,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TransferCharacteristic :: enum u8 {
|
|
|
|
|
RESERVED_0 = 0,
|
|
|
|
|
BT_709 = 1,
|
|
|
|
|
UNSPECIFIED = 2,
|
|
|
|
|
RESERVED_3 = 3,
|
|
|
|
|
BT_470_M = 4,
|
|
|
|
|
BT_470_B_G = 5,
|
|
|
|
|
BT_601 = 6,
|
|
|
|
|
SMPTE_240 = 7,
|
|
|
|
|
LINEAR = 8,
|
|
|
|
|
LOG_100 = 9,
|
|
|
|
|
LOG_100_SQRT10 = 10,
|
|
|
|
|
IEC_61966 = 11,
|
|
|
|
|
BT_1361 = 12,
|
|
|
|
|
SRGB = 13,
|
|
|
|
|
BT_2020_10_BIT = 14,
|
|
|
|
|
BT_2020_12_BIT = 15,
|
|
|
|
|
SMPTE_2084 = 16,
|
|
|
|
|
SMPTE_428 = 17,
|
|
|
|
|
HLG = 18,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MatrixCoefficient :: enum u8 {
|
|
|
|
|
IDENTITY = 0,
|
|
|
|
|
BT_709 = 1,
|
|
|
|
|
UNSPECIFIED = 2,
|
|
|
|
|
RESERVED_3 = 3,
|
|
|
|
|
FCC = 4,
|
|
|
|
|
BT_470_B_G = 5,
|
|
|
|
|
BT_601 = 6,
|
|
|
|
|
SMPTE_240 = 7,
|
|
|
|
|
SMPTE_YCGCO = 8,
|
|
|
|
|
BT_2020_NCL = 9,
|
|
|
|
|
BT_2020_CL = 10,
|
|
|
|
|
SMPTE_2085 = 11,
|
|
|
|
|
CHROMAT_NCL = 12,
|
|
|
|
|
CHROMAT_CL = 13,
|
|
|
|
|
ICTCP = 14,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ChromeSamplePosition :: enum u8 {
|
|
|
|
|
UNKNOWN = 0,
|
|
|
|
|
VERTICAL = 1,
|
|
|
|
|
COLOCATED = 2,
|
|
|
|
|
RESERVED = 3,
|
2024-05-02 12:12:13 +02:00
|
|
|
}
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
ColorRange :: enum u8 {
|
|
|
|
|
LIMITED = 0,
|
|
|
|
|
FULL = 1,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FrameType :: enum u8 {
|
|
|
|
|
KEY_FRAME = 0,
|
|
|
|
|
INTER_FRAME = 1,
|
|
|
|
|
INTRA_ONLY_FRAME = 2,
|
|
|
|
|
SWITCH_FRAME = 3,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Maybe just make these constants??
|
|
|
|
|
RefFrame0 :: enum u8 {
|
|
|
|
|
INTRA_FRAME = 0,
|
|
|
|
|
LAST_FRAME = 1,
|
|
|
|
|
LAST2_FRAME = 2,
|
|
|
|
|
LAST3_FRAME = 3,
|
|
|
|
|
GOLDEN_FRAME = 4,
|
|
|
|
|
BWDREF_FRAME = 5,
|
|
|
|
|
ALTREF2_FRAME = 6,
|
|
|
|
|
ALTREF_FRAME = 7,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RefFrame1 :: enum i8 {
|
|
|
|
|
NONE = -1,
|
|
|
|
|
INTRA_FRAME = 0,
|
|
|
|
|
LAST_FRAME = 1,
|
|
|
|
|
LAST2_FRAME = 2,
|
|
|
|
|
LAST3_FRAME = 3,
|
|
|
|
|
GOLDEN_FRAME = 4,
|
|
|
|
|
BWDREF_FRAME = 5,
|
|
|
|
|
ALTREF2_FRAME = 6,
|
|
|
|
|
ALTREF_FRAME = 7,
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-02 12:12:13 +02:00
|
|
|
OBUHeader :: bit_field u8 {
|
|
|
|
|
obu_reserved: u8 | 1,
|
2024-05-03 01:42:45 +02:00
|
|
|
obu_has_size_field: b8 | 1,
|
|
|
|
|
obu_extension_flag: b8 | 1,
|
2024-05-02 12:12:13 +02:00
|
|
|
obu_type: OBUType | 4,
|
|
|
|
|
obu_forbidden_bit: u8 | 1,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OBUExtensionHeader :: bit_field u8 {
|
|
|
|
|
extension_header_reserved: u8 | 3,
|
|
|
|
|
spatial_id: u8 | 2,
|
|
|
|
|
temporal_id: u8 | 3,
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
SequenceHeader :: struct {
|
|
|
|
|
enable_superres: bool,
|
|
|
|
|
enable_cdef: bool,
|
|
|
|
|
enable_restoration: bool,
|
|
|
|
|
film_grain_params_present: bool,
|
|
|
|
|
seq_profile: u8,
|
|
|
|
|
BitDepth: u8,
|
|
|
|
|
mono_chrome: bool,
|
|
|
|
|
num_planes: u8,
|
|
|
|
|
color_primaries: ColorPrimaries,
|
|
|
|
|
transfer_characteristic: TransferCharacteristic,
|
|
|
|
|
matrix_coefficients: MatrixCoefficient,
|
|
|
|
|
chroma_sample_position: ChromeSamplePosition,
|
|
|
|
|
subsampling_x: u8,
|
|
|
|
|
subsampling_y: u8,
|
|
|
|
|
separate_uv_delta_q: u8,
|
|
|
|
|
color_range: ColorRange,
|
|
|
|
|
OrderHintBits: u8,
|
|
|
|
|
num_ticks_per_picture_minus_1: u64,
|
|
|
|
|
time_scale: u32,
|
|
|
|
|
num_units_in_display_tick: u32,
|
|
|
|
|
buffer_delay_length_minus_1: u8,
|
|
|
|
|
num_units_in_decoding_tick: u32,
|
|
|
|
|
buffer_removal_time_length_minus_1: u8,
|
|
|
|
|
frame_presentation_time_length_minus_1: u8,
|
|
|
|
|
initial_display_delay_minus_1: [MAX_OPERATING_POINTS]u8,
|
|
|
|
|
decoder_buffer_delay: [MAX_OPERATING_POINTS]u64,
|
|
|
|
|
encoder_buffer_delay: [MAX_OPERATING_POINTS]u64,
|
|
|
|
|
low_delay_mode_flag: [MAX_OPERATING_POINTS]bool,
|
|
|
|
|
operating_point_idc_arr: [MAX_OPERATING_POINTS]u16,
|
|
|
|
|
seq_level_idx: [MAX_OPERATING_POINTS]u8,
|
|
|
|
|
seq_tier: [MAX_OPERATING_POINTS]u8,
|
|
|
|
|
decoder_model_present_for_this_op: [MAX_OPERATING_POINTS]bool,
|
|
|
|
|
initial_display_delay_present_for_this_op: [MAX_OPERATING_POINTS]bool,
|
|
|
|
|
frame_id_numbers_present_flag: bool,
|
|
|
|
|
additional_frame_id_length_minus_1: u8,
|
|
|
|
|
delta_frame_id_length_minus_2: u8,
|
|
|
|
|
reduced_still_picture_header: bool,
|
|
|
|
|
equal_picture_interval: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FrameHeader :: struct {
|
|
|
|
|
SeenFrameHeader: bool,
|
|
|
|
|
TileNum: u64,
|
|
|
|
|
show_existing_frame: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
read_obu :: proc(r: ^Reader, seq_header: ^SequenceHeader, frame_header: ^FrameHeader) -> (err: Error) {
|
2024-05-03 01:42:45 +02:00
|
|
|
header := read_bitfield(r, OBUHeader) or_return
|
|
|
|
|
size: u64
|
|
|
|
|
|
|
|
|
|
fmt.println(header)
|
|
|
|
|
|
|
|
|
|
if header.obu_extension_flag {
|
|
|
|
|
ext_header := read_bitfield(r, OBUExtensionHeader) or_return
|
|
|
|
|
|
|
|
|
|
fmt.println(ext_header)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if header.obu_has_size_field {
|
|
|
|
|
size = leb128(r)
|
|
|
|
|
} else {
|
|
|
|
|
// TODO: is this correct ???
|
|
|
|
|
// The spec is NOT clear about wtf sz is, so I assume it's the box size without the header.
|
|
|
|
|
// It's also possibly the remaining box size, we'll have to check how other decoders do it.
|
|
|
|
|
size = u64(r.box.size - BOX_HEADER_SIZE - 1 - u32(header.obu_extension_flag))
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
start_pos := r.i * 8 + i64(r.bits_read_in_byte)
|
2024-05-03 01:42:45 +02:00
|
|
|
|
|
|
|
|
//// TODO:
|
|
|
|
|
//if header.obu_type != .SEQUENCE_HEADER && header.obu_type != .TEMPORAL_DELIMITER && OperatingPointIdc != 0 && header.obu_extension_flag == 1 {
|
2024-05-04 03:24:01 +02:00
|
|
|
// inTemporalLayer := (OperatingPointIdc >> temporal_id) & 1
|
|
|
|
|
// inSpatialLayer := (OperatingPointIdc >> (spatial_id + 8)) & 1
|
2024-05-02 12:12:13 +02:00
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
// if inTemporalLayer == 0 || inSpatialLayer == 0 {
|
2024-05-03 01:42:45 +02:00
|
|
|
// drop_obu()
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
fmt.println("OBU size:", size)
|
|
|
|
|
|
|
|
|
|
if header.obu_type != .SEQUENCE_HEADER &&
|
|
|
|
|
header.obu_type != .TEMPORAL_DELIMITER &&
|
|
|
|
|
header.obu_type != .FRAME_HEADER &&
|
|
|
|
|
header.obu_type != .TILE_GROUP &&
|
|
|
|
|
header.obu_type != .METADATA &&
|
|
|
|
|
header.obu_type != .FRAME &&
|
|
|
|
|
header.obu_type != .REDUNDANT_FRAME_HEADER &&
|
|
|
|
|
header.obu_type != .TILE_LIST &&
|
|
|
|
|
header.obu_type != .PADDING {
|
|
|
|
|
return .ReservedOBU
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#partial switch header.obu_type {
|
|
|
|
|
case .TEMPORAL_DELIMITER:
|
|
|
|
|
// do nothing. the temporal OBU has an empty payload
|
|
|
|
|
case .SEQUENCE_HEADER:
|
2024-05-04 03:24:01 +02:00
|
|
|
parse_sequence_header_obu(r, seq_header)
|
|
|
|
|
fmt.println(seq_header)
|
|
|
|
|
case .FRAME_HEADER:
|
|
|
|
|
parse_frame_header_obu(r, size, seq_header, frame_header)
|
2024-05-03 01:42:45 +02:00
|
|
|
case .FRAME:
|
2024-05-04 03:24:01 +02:00
|
|
|
parse_frame_obu(r, size, seq_header, frame_header)
|
2024-05-03 01:42:45 +02:00
|
|
|
}
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
current_pos := r.i * 8 + i64(r.bits_read_in_byte)
|
|
|
|
|
payload_bits := current_pos - start_pos
|
2024-05-03 01:42:45 +02:00
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
fmt.println("start pos", start_pos)
|
|
|
|
|
fmt.println("current pos", current_pos)
|
|
|
|
|
fmt.println("payload_bits", payload_bits)
|
|
|
|
|
fmt.println("trailing bits", size * 8 - u64(payload_bits))
|
|
|
|
|
|
|
|
|
|
if size > 0 && header.obu_type != .TILE_GROUP && header.obu_type != .TILE_LIST && header.obu_type != .FRAME {
|
|
|
|
|
trailing_bits(r, size * 8 - u64(payload_bits))
|
|
|
|
|
}
|
2024-05-03 01:42:45 +02:00
|
|
|
|
|
|
|
|
return nil
|
2024-05-02 12:12:13 +02:00
|
|
|
}
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
trailing_bits :: proc(r: ^Reader, nbits: u64) {
|
|
|
|
|
nbits := nbits
|
|
|
|
|
trailing_one_bit := f(r, 1)
|
|
|
|
|
nbits -= 1
|
|
|
|
|
|
|
|
|
|
for nbits > 0 {
|
|
|
|
|
trailing_one_bit = f(r, 1)
|
|
|
|
|
nbits -= 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
timing_info :: proc(r: ^Reader, seq_header: ^SequenceHeader) {
|
|
|
|
|
seq_header.num_units_in_display_tick = auto_cast f(r, 32)
|
|
|
|
|
seq_header.time_scale = auto_cast f(r, 32)
|
|
|
|
|
seq_header.equal_picture_interval = auto_cast f(r, 32)
|
|
|
|
|
if seq_header.equal_picture_interval {
|
|
|
|
|
seq_header.num_ticks_per_picture_minus_1 = uvlc(r)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
decoder_model_info :: proc(r: ^Reader, seq_header: ^SequenceHeader) {
|
|
|
|
|
seq_header.buffer_delay_length_minus_1 = auto_cast f(r, 5)
|
|
|
|
|
seq_header.num_units_in_decoding_tick = auto_cast f(r, 32)
|
|
|
|
|
seq_header.buffer_removal_time_length_minus_1 = auto_cast f(r, 5)
|
|
|
|
|
seq_header.frame_presentation_time_length_minus_1 = auto_cast f(r, 5)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
operating_parameters_info :: proc(r: ^Reader, op: u8, seq_header: ^SequenceHeader) {
|
|
|
|
|
n := seq_header.buffer_delay_length_minus_1 + 1
|
|
|
|
|
seq_header.decoder_buffer_delay[op] = f(r, auto_cast n)
|
|
|
|
|
seq_header.encoder_buffer_delay[op] = f(r, auto_cast n)
|
|
|
|
|
seq_header.low_delay_mode_flag[op] = auto_cast f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
color_config :: proc(r: ^Reader, seq_header: ^SequenceHeader) {
|
|
|
|
|
high_bitdepth := bool(f(r, 1))
|
|
|
|
|
|
|
|
|
|
if seq_header.seq_profile == 2 && high_bitdepth {
|
|
|
|
|
twelve_bit := bool(f(r, 1))
|
|
|
|
|
seq_header.BitDepth = twelve_bit ? 12 : 10
|
|
|
|
|
} else if seq_header.seq_profile <= 2 {
|
|
|
|
|
seq_header.BitDepth = high_bitdepth ? 10 : 8
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if seq_header.seq_profile == 1 {
|
|
|
|
|
seq_header.mono_chrome = false
|
|
|
|
|
} else {
|
|
|
|
|
seq_header.mono_chrome = auto_cast f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seq_header.num_planes = seq_header.mono_chrome ? 1 : 3
|
|
|
|
|
color_description_present_flag: bool = auto_cast f(r, 1)
|
|
|
|
|
|
|
|
|
|
if color_description_present_flag {
|
|
|
|
|
seq_header.color_primaries = auto_cast f(r, 8)
|
|
|
|
|
seq_header.transfer_characteristic = auto_cast f(r, 8)
|
|
|
|
|
seq_header.matrix_coefficients = auto_cast f(r, 8)
|
|
|
|
|
} else {
|
|
|
|
|
seq_header.color_primaries = .UNSPECIFIED
|
|
|
|
|
seq_header.transfer_characteristic = .UNSPECIFIED
|
|
|
|
|
seq_header.matrix_coefficients = .UNSPECIFIED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if seq_header.mono_chrome {
|
|
|
|
|
seq_header.color_range = auto_cast f(r, 1)
|
|
|
|
|
seq_header.subsampling_x = 1
|
|
|
|
|
seq_header.subsampling_y = 1
|
|
|
|
|
seq_header.chroma_sample_position = .UNKNOWN
|
|
|
|
|
seq_header.separate_uv_delta_q = 0
|
|
|
|
|
return
|
|
|
|
|
} else if seq_header.color_primaries == .BT_709 && seq_header.transfer_characteristic == .SRGB && seq_header.matrix_coefficients == .IDENTITY {
|
|
|
|
|
seq_header.color_range = .FULL
|
|
|
|
|
seq_header.subsampling_x = 0
|
|
|
|
|
seq_header.subsampling_y = 0
|
|
|
|
|
} else {
|
|
|
|
|
seq_header.color_range = auto_cast f(r, 1)
|
|
|
|
|
|
|
|
|
|
if seq_header.seq_profile == 0 {
|
|
|
|
|
seq_header.subsampling_x = 1
|
|
|
|
|
seq_header.subsampling_y = 1
|
|
|
|
|
} else if seq_header.seq_profile == 1 {
|
|
|
|
|
seq_header.subsampling_x = 0
|
|
|
|
|
seq_header.subsampling_y = 0
|
|
|
|
|
} else {
|
|
|
|
|
if seq_header.BitDepth == 12 {
|
|
|
|
|
seq_header.subsampling_x = auto_cast f(r, 1)
|
|
|
|
|
|
|
|
|
|
if seq_header.subsampling_x == 1 {
|
|
|
|
|
seq_header.subsampling_y = auto_cast f(r, 1)
|
|
|
|
|
} else {
|
|
|
|
|
seq_header.subsampling_y = 0
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
seq_header.subsampling_x = 1
|
|
|
|
|
seq_header.subsampling_y = 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if seq_header.subsampling_x == 1 && seq_header.subsampling_y == 1 {
|
|
|
|
|
seq_header.chroma_sample_position = auto_cast f(r, 2)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seq_header.separate_uv_delta_q = auto_cast f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parse_sequence_header_obu :: proc(r: ^Reader, seq_header: ^SequenceHeader) -> (OBUError) {
|
2024-05-03 01:42:45 +02:00
|
|
|
seq_profile := f(r, 3)
|
2024-05-04 03:24:01 +02:00
|
|
|
if seq_profile > 2 {
|
|
|
|
|
return .ReservedSeqProfile
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-03 01:42:45 +02:00
|
|
|
still_picture := f(r, 1)
|
2024-05-04 03:24:01 +02:00
|
|
|
seq_header.reduced_still_picture_header := auto_cast f(r, 1)
|
2024-05-03 01:42:45 +02:00
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
timing_info_present_flag: bool
|
|
|
|
|
decoder_model_info_present_flag: bool
|
|
|
|
|
initial_display_delay_present_flag: bool
|
2024-05-03 01:42:45 +02:00
|
|
|
operating_points_cnt_minus_1: u8
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
if seq_header.reduced_still_picture_header {
|
2024-05-03 01:42:45 +02:00
|
|
|
// TODO: should these be saved as state ??
|
2024-05-04 03:24:01 +02:00
|
|
|
timing_info_present_flag = false
|
|
|
|
|
decoder_model_info_present_flag = false
|
|
|
|
|
initial_display_delay_present_flag = false
|
2024-05-03 01:42:45 +02:00
|
|
|
operating_points_cnt_minus_1 = 0
|
2024-05-04 03:24:01 +02:00
|
|
|
seq_header.operating_point_idc_arr[0] = 0
|
|
|
|
|
seq_header.seq_level_idx[0] = auto_cast f(r, 5)
|
|
|
|
|
seq_header.seq_tier[0] = 0
|
|
|
|
|
seq_header.decoder_model_present_for_this_op[0] = false
|
|
|
|
|
seq_header.initial_display_delay_present_for_this_op[0] = false
|
2024-05-03 01:42:45 +02:00
|
|
|
} else {
|
2024-05-04 03:24:01 +02:00
|
|
|
timing_info_present_flag = auto_cast f(r, 1)
|
|
|
|
|
|
|
|
|
|
if timing_info_present_flag {
|
|
|
|
|
timing_info(r, seq_header)
|
|
|
|
|
|
|
|
|
|
decoder_model_info_present_flag = auto_cast f(r, 1)
|
|
|
|
|
if decoder_model_info_present_flag {
|
|
|
|
|
decoder_model_info(r, seq_header)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
decoder_model_info_present_flag = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initial_display_delay_present_flag = auto_cast f(r, 1)
|
|
|
|
|
operating_points_cnt_minus_1 = auto_cast f(r, 5)
|
|
|
|
|
|
|
|
|
|
for i in 0 ..=operating_points_cnt_minus_1 {
|
|
|
|
|
seq_header.operating_point_idc_arr[i] = auto_cast f(r, 12)
|
|
|
|
|
seq_header.seq_level_idx[i] = auto_cast f(r, 5)
|
|
|
|
|
|
|
|
|
|
if seq_header.seq_level_idx[i] > 7 {
|
|
|
|
|
seq_header.seq_tier[i] = auto_cast f(r, 1)
|
|
|
|
|
} else {
|
|
|
|
|
seq_header.seq_tier[i] = 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if decoder_model_info_present_flag {
|
|
|
|
|
seq_header.decoder_model_present_for_this_op[i] = auto_cast f(r, 1)
|
|
|
|
|
if seq_header.decoder_model_present_for_this_op[i] {
|
|
|
|
|
operating_parameters_info(r, i, seq_header)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
seq_header.decoder_model_present_for_this_op[i] = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if initial_display_delay_present_flag {
|
|
|
|
|
seq_header.initial_display_delay_present_for_this_op[i] = auto_cast f(r, 1)
|
|
|
|
|
if seq_header.initial_display_delay_present_for_this_op[i] {
|
|
|
|
|
seq_header.initial_display_delay_minus_1[i] = auto_cast f(r, 4)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-03 01:42:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.println("seq_profile:", seq_profile)
|
|
|
|
|
fmt.println("still_picture:", still_picture)
|
2024-05-04 03:24:01 +02:00
|
|
|
fmt.println("reduced_still_picture_header:", seq_header.reduced_still_picture_header)
|
2024-05-03 01:42:45 +02:00
|
|
|
|
|
|
|
|
fmt.println("timing_info_present_flag:", timing_info_present_flag)
|
|
|
|
|
fmt.println("decoder_model_info_present_flag:", decoder_model_info_present_flag)
|
|
|
|
|
fmt.println("initial_display_delay_present_flag:", initial_display_delay_present_flag)
|
|
|
|
|
fmt.println("operating_points_cnt_minus_1:", operating_points_cnt_minus_1)
|
|
|
|
|
|
|
|
|
|
//operating_point := choose_operating_point()
|
2024-05-04 03:24:01 +02:00
|
|
|
//operating_point_idc := seq_header.operating_point_idc_arr[operating_point]
|
2024-05-03 01:42:45 +02:00
|
|
|
frame_width_bits_minus_1 := f(r, 4)
|
|
|
|
|
frame_height_bits_minus_1 := f(r, 4)
|
|
|
|
|
n := frame_width_bits_minus_1 + 1
|
|
|
|
|
max_frame_width_minus_1 := f(r, auto_cast n)
|
|
|
|
|
n = frame_height_bits_minus_1 + 1
|
|
|
|
|
max_frame_height_minus_1 := f(r, auto_cast n)
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
if seq_header.reduced_still_picture_header {
|
|
|
|
|
seq_header.frame_id_numbers_present_flag = false
|
2024-05-03 01:42:45 +02:00
|
|
|
} else {
|
2024-05-04 03:24:01 +02:00
|
|
|
seq_header.frame_id_numbers_present_flag = auto_cast f(r, 1)
|
2024-05-03 01:42:45 +02:00
|
|
|
}
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
if seq_header.frame_id_numbers_present_flag {
|
|
|
|
|
seq_header.delta_frame_id_length_minus_2 = auto_cast f(r, 4)
|
|
|
|
|
seq_header.additional_frame_id_length_minus_1 = auto_cast f(r, 3)
|
2024-05-03 01:42:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
use_128x128_superblock := f(r, 1)
|
|
|
|
|
enable_filter_intra := f(r, 1)
|
|
|
|
|
enable_intra_edge_filter := f(r, 1)
|
|
|
|
|
|
|
|
|
|
fmt.println("frame_width_bits_minus_1:", frame_width_bits_minus_1)
|
|
|
|
|
fmt.println("frame_height_bits_minus_1:", frame_height_bits_minus_1)
|
|
|
|
|
fmt.println("max_frame_width_minus_1:", max_frame_width_minus_1)
|
|
|
|
|
fmt.println("max_frame_height_minus_1:", max_frame_height_minus_1)
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
fmt.println("frame_id_numbers_present_flag:", seq_header.frame_id_numbers_present_flag)
|
|
|
|
|
fmt.println("delta_frame_id_length_minus_2:", seq_header.delta_frame_id_length_minus_2)
|
|
|
|
|
fmt.println("additional_frame_id_length_minus_1:", seq_header.additional_frame_id_length_minus_1)
|
2024-05-03 01:42:45 +02:00
|
|
|
|
|
|
|
|
fmt.println("use_128x128_superblock:", use_128x128_superblock)
|
|
|
|
|
fmt.println("enable_filter_intra:", enable_filter_intra)
|
|
|
|
|
fmt.println("enable_intra_edge_filter:", enable_intra_edge_filter)
|
|
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
enable_interintra_compound: u8
|
|
|
|
|
enable_masked_compound: u8
|
|
|
|
|
enable_warped_motion: u8
|
|
|
|
|
enable_dual_filter: u8
|
|
|
|
|
enable_order_hint: bool
|
|
|
|
|
enable_jnt_comp: u8
|
|
|
|
|
enable_ref_frame_mvs: u8
|
|
|
|
|
seq_force_screen_content_tools: u8
|
|
|
|
|
seq_force_integer_mv: u8
|
|
|
|
|
|
|
|
|
|
if seq_header.reduced_still_picture_header {
|
|
|
|
|
enable_interintra_compound = 0
|
|
|
|
|
enable_masked_compound = 0
|
|
|
|
|
enable_warped_motion = 0
|
|
|
|
|
enable_dual_filter = 0
|
|
|
|
|
enable_order_hint = false
|
|
|
|
|
enable_jnt_comp = 0
|
|
|
|
|
enable_ref_frame_mvs = 0
|
|
|
|
|
seq_force_screen_content_tools = SELECT_SCREEN_CONTENT_TOOLS
|
|
|
|
|
seq_force_integer_mv = SELECT_INTEGER_MV
|
|
|
|
|
seq_header.OrderHintBits = 0
|
|
|
|
|
} else {
|
|
|
|
|
enable_interintra_compound = auto_cast f(r, 1)
|
|
|
|
|
enable_masked_compound = auto_cast f(r, 1)
|
|
|
|
|
enable_warped_motion = auto_cast f(r, 1)
|
|
|
|
|
enable_dual_filter = auto_cast f(r, 1)
|
|
|
|
|
enable_order_hint = auto_cast f(r, 1)
|
|
|
|
|
if enable_order_hint {
|
|
|
|
|
enable_jnt_comp = auto_cast f(r, 1)
|
|
|
|
|
enable_ref_frame_mvs = auto_cast f(r, 1)
|
|
|
|
|
} else {
|
|
|
|
|
enable_jnt_comp = 0
|
|
|
|
|
enable_ref_frame_mvs = 0
|
|
|
|
|
}
|
2024-05-03 01:42:45 +02:00
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
seq_choose_screen_content_tools: bool = auto_cast f(r, 1)
|
|
|
|
|
if seq_choose_screen_content_tools {
|
|
|
|
|
seq_force_screen_content_tools = SELECT_SCREEN_CONTENT_TOOLS
|
|
|
|
|
} else {
|
|
|
|
|
seq_force_screen_content_tools = auto_cast f(r, 1)
|
|
|
|
|
}
|
2024-05-03 01:42:45 +02:00
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
if seq_force_screen_content_tools > 0 {
|
|
|
|
|
seq_choose_integer_mv: bool = auto_cast f(r, 1)
|
|
|
|
|
if seq_choose_integer_mv {
|
|
|
|
|
seq_force_integer_mv = SELECT_INTEGER_MV
|
|
|
|
|
} else {
|
|
|
|
|
seq_force_integer_mv = auto_cast f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
seq_force_integer_mv = SELECT_INTEGER_MV
|
|
|
|
|
}
|
2024-05-03 01:42:45 +02:00
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
if enable_order_hint {
|
|
|
|
|
order_hint_bits_minus_1 := f(r, 3)
|
|
|
|
|
seq_header.OrderHintBits = u8(order_hint_bits_minus_1) + 1
|
|
|
|
|
} else {
|
|
|
|
|
seq_header.OrderHintBits = 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seq_header.enable_superres = auto_cast f(r, 1)
|
|
|
|
|
seq_header.enable_cdef = auto_cast f(r, 1)
|
|
|
|
|
seq_header.enable_restoration = auto_cast f(r, 1)
|
|
|
|
|
color_config(r, seq_header)
|
|
|
|
|
seq_header.film_grain_params_present = auto_cast f(r, 1)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2024-05-03 01:42:45 +02:00
|
|
|
|
2024-05-04 03:24:01 +02:00
|
|
|
byte_alignment :: proc(r: ^Reader) {
|
|
|
|
|
pos := r.i * 8 + i64(r.bits_read_in_byte)
|
|
|
|
|
for pos & 7 == 1 {
|
|
|
|
|
f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parse_frame_obu :: proc(r: ^Reader, size: u64, seq_header: ^SequenceHeader, frame_header: ^FrameHeader) {
|
|
|
|
|
size := size
|
|
|
|
|
|
|
|
|
|
start_bit_pos := r.i * 8 + i64(r.bits_read_in_byte)
|
|
|
|
|
parse_frame_header_obu(r, seq_header, frame_header)
|
|
|
|
|
byte_alignment(r)
|
|
|
|
|
end_bit_pos := r.i * 8 + i64(r.bits_read_in_byte)
|
|
|
|
|
header_bytes := (end_bit_pos - start_bit_pos) / 8
|
|
|
|
|
size -= u64(header_bytes)
|
|
|
|
|
parse_tile_group_obu(r, size)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uncompressed_header :: proc(r: ^Reader, seq_header: ^SequenceHeader, frame_header: ^FrameHeader) {
|
|
|
|
|
if seq_header.frame_id_numbers_present_flag {
|
|
|
|
|
idLen := seq_header.additional_frame_id_length_minus_1 + seq_header.delta_frame_id_length_minus_2 + 3
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
allFrames := (1 << NUM_REF_FRAMES) - 1
|
|
|
|
|
if seq_header.reduced_still_picture_header {
|
|
|
|
|
frame_header.show_existing_frame = false
|
|
|
|
|
frame_type = .KEY_FRAME
|
|
|
|
|
FrameIsIntra = true
|
|
|
|
|
show_frame = true
|
|
|
|
|
showable_frame = false
|
|
|
|
|
} else {
|
|
|
|
|
frame_header.show_existing_frame = auto_cast f(r, 1)
|
|
|
|
|
if frame_header.show_existing_frame {
|
|
|
|
|
frame_to_show_map_idx = f(r, 3)
|
|
|
|
|
if seq_header.decoder_model_info_present_flag && !seq_header.equal_picture_interval {
|
|
|
|
|
temporal_point_info()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
refresh_frame_flags = 0
|
|
|
|
|
|
|
|
|
|
if seq_header.frame_id_numbers_present_flag {
|
|
|
|
|
display_frame_id = f(r, idLen)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
frame_type = RefFrameType[frame_to_show_map_idx]
|
|
|
|
|
if frame_type == .KEY_FRAME {
|
|
|
|
|
refresh_frame_flags = allFrames
|
|
|
|
|
}
|
|
|
|
|
if seq_header.film_grain_params_present {
|
|
|
|
|
load_grain_params(frame_to_show_map_idx)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
frame_type = f(r, 2)
|
|
|
|
|
FrameIsIntra = frame_type == .INTRA_ONLY_FRAME || frame_type == .KEY_FRAME
|
|
|
|
|
show_frame = f(r, 1)
|
|
|
|
|
|
|
|
|
|
if show_frame && seq_header.decoder_model_info_present_flag && !seq_header.equal_picture_interval {
|
|
|
|
|
temporal_point_info()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if show_frame {
|
|
|
|
|
showable_frame = frame_type != .KEY_FRAME
|
|
|
|
|
} else {
|
|
|
|
|
showable_frame = f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if frame_type == .SWITCH_FRAME || (frame_type == .KEY_FRAME && show_frame) {
|
|
|
|
|
error_resilient_mode = 1
|
|
|
|
|
} else {
|
|
|
|
|
error_resilient_mode = f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if frame_type == .KEY_FRAME && show_frame {
|
|
|
|
|
for i in 0..<NUM_REF_FRAMES {
|
|
|
|
|
RefValid[i] = 0
|
|
|
|
|
RefOrderHint[i] = 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i in 0..<REFS_PER_FRAME {
|
|
|
|
|
OrderHints[.LAST_FRAME + i] = 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
disable_cdf_update = f(r, 1)
|
|
|
|
|
|
|
|
|
|
if seq_force_screen_content_tools == SELECT_SCREEN_CONTENT_TOOLS {
|
|
|
|
|
allow_screen_content_tools = f(r, 1)
|
|
|
|
|
} else {
|
|
|
|
|
allow_screen_content_tools = seq_force_screen_content_tools
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if allow_screen_content_tools {
|
|
|
|
|
if seq_force_integer_mv == SELECT_INTEGER_MV {
|
|
|
|
|
force_integer_mv = f(r, 1)
|
|
|
|
|
} else {
|
|
|
|
|
force_integer_mv = seq_force_integer_mv
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
force_integer_mv = 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if FrameIsIntra {
|
|
|
|
|
force_integer_mv = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if seq_header.frame_id_numbers_present_flag {
|
|
|
|
|
PrevFrameID = current_frame_id
|
|
|
|
|
current_frame_id = f(r, idLen)
|
|
|
|
|
mark_ref_frames(idLen)
|
|
|
|
|
} else {
|
|
|
|
|
current_frame_id = 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if frame_type == .SWITCH_FRAME {
|
|
|
|
|
frame_size_override_flag = 1
|
|
|
|
|
} else if seq_header.reduced_still_picture_header {
|
|
|
|
|
frame_size_override_flag = 0
|
|
|
|
|
} else {
|
|
|
|
|
frame_size_override_flag = f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
order_hint = f(seq_header.OrderHintBits)
|
|
|
|
|
OrderHint = order_hint
|
|
|
|
|
|
|
|
|
|
if FrameIsIntra || error_resilient_mode {
|
|
|
|
|
primary_ref_frame = PRIMARY_REF_NONE
|
|
|
|
|
} else {
|
|
|
|
|
primary_ref_frame = f(r, 3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if seq_header.decoder_model_info_present_flag {
|
|
|
|
|
buffer_removal_time_present_flag = f(r, 1)
|
|
|
|
|
|
|
|
|
|
if buffer_removal_time_present_flag {
|
|
|
|
|
for opNum in 0..=operating_points_cnt_minus_1 {
|
|
|
|
|
if seq_header.decoder_model_present_for_this_op[opNum] {
|
|
|
|
|
opPtIdc = seq_header.operating_point_idc_arr[opNum]
|
|
|
|
|
inTemporalLayer = (opPtIdc >> temporal_id) & 1
|
|
|
|
|
inSpatialLayer = (opPtIdc >> (spatial_id + 8)) & 1
|
|
|
|
|
if opPtIdc == 0 || (inTemporalLayer && inSpatialLayer) {
|
|
|
|
|
n = buffer_removal_time_length_minus_1 + 1
|
|
|
|
|
buffer_removal_time[opNum]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
allow_high_precision_mv = 0
|
|
|
|
|
use_ref_frame_mvs = 0
|
|
|
|
|
allow_intrabc = 0
|
|
|
|
|
|
|
|
|
|
if frame_type == .SWITCH_FRAME || (frame_type == .KEY_FRAME && show_frame) {
|
|
|
|
|
refresh_frame_flags = allFrames
|
|
|
|
|
} else {
|
|
|
|
|
refresh_frame_flags = f(r, 8)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !FrameIsIntra || refresh_frame_flags != allFrames {
|
|
|
|
|
if error_resilient_mode && enable_order_hint {
|
|
|
|
|
for i in 0..<NUM_REF_FRAMES {
|
|
|
|
|
ref_order_hint[i] = f(r, OrderHintBits)
|
|
|
|
|
if ref_order_hint[i] != RefOrderHint[i] {
|
|
|
|
|
RefValid[i] = 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if FrameIsIntra {
|
|
|
|
|
frame_size()
|
|
|
|
|
render_size()
|
|
|
|
|
if allow_screen_content_tools && UpscaledWidth == FrameWidth {
|
|
|
|
|
allow_intrabc = f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if !enable_order_hint {
|
|
|
|
|
frame_refs_short_signaling = 0
|
|
|
|
|
} else {
|
|
|
|
|
frame_refs_short_signaling = f(r, 1)
|
|
|
|
|
if frame_refs_short_signaling {
|
|
|
|
|
last_frame_id = f(r, 3)
|
|
|
|
|
gold_frame_id = f(r, 3)
|
|
|
|
|
set_frame_refs()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i in 0..<REFS_PER_FRAME {
|
|
|
|
|
if !frame_refs_short_signaling {
|
|
|
|
|
ref_frame_idx[i] = f(r, 3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if seq_header.frame_id_numbers_present_flag {
|
|
|
|
|
n = delta_frame_id_length_minus_2 + 2
|
|
|
|
|
delta_frame_id_minus_1 = f(r, n)
|
|
|
|
|
DeltaFrameId = delta_frame_id_minus_1 + 1
|
|
|
|
|
expectedFrameId[i] = (current_frame_id + (1 << idLen) - DeltaFrameId ) % (1 << idLen)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if frame_size_override_flag && !error_resilient_mode {
|
|
|
|
|
frame_size_with_refs()
|
|
|
|
|
} else {
|
|
|
|
|
frame_size()
|
|
|
|
|
render_size()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if force_integer_mv {
|
|
|
|
|
allow_high_precision_mv = 0
|
|
|
|
|
} else {
|
|
|
|
|
allow_high_precision_mv = f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
read_interpolation_filter()
|
|
|
|
|
is_motion_mode_switchable = f(r, 1)
|
|
|
|
|
|
|
|
|
|
if error_resilient_mode || !enable_ref_frame_mvs {
|
|
|
|
|
use_ref_frame_mvs = 0
|
|
|
|
|
} else {
|
|
|
|
|
use_ref_frame_mvs = f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i in 0..<REFS_PER_FRAME {
|
|
|
|
|
refFrame = LAST_FRAME + i
|
|
|
|
|
hint = RefOrderHint[ref_frame_idx[i]]
|
|
|
|
|
OrderHints[refFrame] = hint
|
|
|
|
|
if !enable_order_hint {
|
|
|
|
|
RefFrameSignBias[refFrame] = 0
|
|
|
|
|
} else {
|
|
|
|
|
RefFrameSignBias[refFrame] = get_relative_dist(hint, OrderHint) > 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if reduced_still_picture_header || disable_cdf_update {
|
|
|
|
|
disable_frame_end_update_cdf = 1
|
|
|
|
|
} else {
|
|
|
|
|
disable_frame_end_update_cdf = f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if primary_ref_frame == PRIMARY_REF_NONE {
|
|
|
|
|
init_non_coeff_cdfs()
|
|
|
|
|
setup_past_independence()
|
|
|
|
|
} else {
|
|
|
|
|
load_cdfs(ref_frame_idx[primary_ref_frame])
|
|
|
|
|
load_previous()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if use_ref_frame_mvs == 1 {
|
|
|
|
|
motion_field_estimation()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tile_info()
|
|
|
|
|
quantization_params()
|
|
|
|
|
segmentation_params()
|
|
|
|
|
delta_q_params()
|
|
|
|
|
delta_lf_params()
|
|
|
|
|
|
|
|
|
|
if primary_ref_frame == PRIMARY_REF_NONE {
|
|
|
|
|
init_coeff_cdfs()
|
|
|
|
|
} else {
|
|
|
|
|
load_previous_segment_ids()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CodedLoseless = 1
|
|
|
|
|
|
|
|
|
|
for segmentId in 0..<MAX_SEGMENTS {
|
|
|
|
|
qindex = get_qindex(1, segmentId)
|
|
|
|
|
LoselessArray[segmentId] = qindex == 0 && DeltaQYDc == 0 && DeltaQUAc == 0 && DeltaQUDc == 0 && DeltaQVAc == 0 && DeltaQVDc == 0
|
|
|
|
|
|
|
|
|
|
if !LoselessArray[segmentId] {
|
|
|
|
|
CodedLoseless = 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if using_qmatrix {
|
|
|
|
|
if LoselessArray[segmentId] {
|
|
|
|
|
SegQMLevel[ 0 ][ segmentId ] = 15
|
|
|
|
|
SegQMLevel[ 1 ][ segmentId ] = 15
|
|
|
|
|
SegQMLevel[ 2 ][ segmentId ] = 15
|
|
|
|
|
} else {
|
|
|
|
|
SegQMLevel[ 0 ][ segmentId ] = qm_y
|
|
|
|
|
SegQMLevel[ 1 ][ segmentId ] = qm_u
|
|
|
|
|
SegQMLevel[ 2 ][ segmentId ] = qm_v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AllLossless = CodedLoseless && (FrameWidth == UpscaledWidth)
|
|
|
|
|
loop_filter_params()
|
|
|
|
|
cdef_params()
|
|
|
|
|
lr_params()
|
|
|
|
|
read_tx_mode()
|
|
|
|
|
frame_reference_mode()
|
|
|
|
|
skip_mode_params()
|
|
|
|
|
|
|
|
|
|
if FrameIsIntra || error_resilient_mode || !enable_warped_motion {
|
|
|
|
|
allow_wraped_motion = 0
|
|
|
|
|
} else {
|
|
|
|
|
allow_wraped_motion = f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reduced_tx_set = f(r, 1)
|
|
|
|
|
global_motion_params()
|
|
|
|
|
film_grain_params()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
frame_header_copy :: proc() {
|
|
|
|
|
// TODO:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
decode_frame_wrapup :: proc(frame_header: ^FrameHeader) {
|
|
|
|
|
// TODO:
|
|
|
|
|
if frame_header.show_existing_frame {
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parse_frame_header_obu :: proc(r: ^Reader, seq_header: ^SequenceHeader, frame_header: ^FrameHeader) {
|
|
|
|
|
if frame_header.SeenFrameHeader {
|
|
|
|
|
frame_header_copy()
|
|
|
|
|
} else {
|
|
|
|
|
frame_header.SeenFrameHeader = true
|
|
|
|
|
uncompressed_header(r, seq_header, frame_header)
|
|
|
|
|
|
|
|
|
|
if frame_header.show_existing_frame {
|
|
|
|
|
decode_frame_wrapup(frame_header)
|
|
|
|
|
frame_header.SeenFrameHeader = false
|
|
|
|
|
} else {
|
|
|
|
|
frame_header.TileNum = 0
|
|
|
|
|
frame_header.SeenFrameHeader = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parse_tile_group_obu :: proc(r: ^Reader, size: u64) {
|
|
|
|
|
size := size
|
|
|
|
|
|
|
|
|
|
NumTiles := TileCols * TileRows
|
|
|
|
|
start_bit_pos := r.i * 8 + i64(r.bits_read_in_byte)
|
|
|
|
|
tile_start_and_end_present_flags := false
|
|
|
|
|
|
|
|
|
|
if NumTiles > 1 {
|
|
|
|
|
tile_start_and_end_present_flags = auto_cast f(r, 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if NumTiles == 1 || !tile_start_and_end_present_flags {
|
|
|
|
|
tg_start = 0
|
|
|
|
|
tg_end = NumTiles - 1
|
|
|
|
|
} else {
|
|
|
|
|
tile_bits = TileColsLog2 + TileRowsLog2
|
|
|
|
|
tg_start = f(r, tile_bits)
|
|
|
|
|
tg_end = f(r, tile_bits)
|
|
|
|
|
}
|
|
|
|
|
byte_alignment(r)
|
|
|
|
|
|
|
|
|
|
end_bit_pos := r.i * 8 + r.bits_read_in_byte
|
|
|
|
|
header_bytes := (end_bit_pos - start_bit_pos) / 8
|
|
|
|
|
size -= header_bytes
|
|
|
|
|
|
|
|
|
|
for TileNum = tg_start; TileNum <= tg_end; TileNum+=1 {
|
|
|
|
|
tile_row := TileNum / TileCols
|
|
|
|
|
tile_col := TileNum % TileCols
|
|
|
|
|
last_tile := TileNum == tg_end
|
|
|
|
|
if last_tile {
|
|
|
|
|
tile_size = size
|
|
|
|
|
} else {
|
|
|
|
|
tile_size_minus_1 := le(TileSizeBytes)
|
|
|
|
|
tile_size = tile_size_minus_1 + 1
|
|
|
|
|
size -= tile_size + TileSizeBytes
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MiRowStart = MiRowStarts[tileRow]
|
|
|
|
|
MiRowEnd = MiRowStarts[tileRow + 1]
|
|
|
|
|
MiColStart = MiColStarts[tileCol]
|
|
|
|
|
MiColEnd = MiColStarts[tileCol + 1]
|
|
|
|
|
CurrentQIndex = base_q_idx
|
|
|
|
|
init_symbol(tile_size)
|
|
|
|
|
decode_tile()
|
|
|
|
|
exit_symbol()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if tg_end == TileNum - 1 {
|
|
|
|
|
if !disable_frame_end_update_cdf {
|
|
|
|
|
frame_end_update_cdf()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
decode_frame_wrapup()
|
|
|
|
|
seen_frame_header = false
|
|
|
|
|
}
|
2024-05-03 01:42:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f :: proc(r: ^Reader, n: int) -> u64 {
|
2024-05-02 12:12:13 +02:00
|
|
|
x: u64 = 0
|
|
|
|
|
|
|
|
|
|
for i in 0 ..< n {
|
2024-05-03 01:42:45 +02:00
|
|
|
// TODO: maybe get rid of or_break and propagate the error??
|
|
|
|
|
x = 2 * x + auto_cast read_bit(r) or_break
|
2024-05-02 12:12:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-03 01:42:45 +02:00
|
|
|
leb128 :: proc(r: ^Reader) -> u64 {
|
2024-05-02 12:12:13 +02:00
|
|
|
value: u64 = 0
|
|
|
|
|
leb128_bytes := 0
|
|
|
|
|
|
|
|
|
|
for i: u64 = 0; i < 8; i += 1 {
|
2024-05-03 01:42:45 +02:00
|
|
|
leb128_byte := f(r, 8)
|
2024-05-02 12:12:13 +02:00
|
|
|
value |= ((leb128_byte & 0x7f) << (i * 7))
|
|
|
|
|
leb128_bytes += 1
|
|
|
|
|
|
|
|
|
|
if (leb128_byte & 0x80) == 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value
|
|
|
|
|
}
|
2024-05-03 01:42:45 +02:00
|
|
|
|
|
|
|
|
uvlc :: proc(r: ^Reader) -> u64 {
|
|
|
|
|
leading_zeros: u64 = 0
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
done := f(r, 1)
|
|
|
|
|
if done == 1 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
leading_zeros += 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if leading_zeros >= 32 {
|
|
|
|
|
return (1 << 32) - 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value := f(r, auto_cast leading_zeros)
|
|
|
|
|
return value + (1 << leading_zeros) - 1
|
|
|
|
|
}
|
2024-05-04 03:24:01 +02:00
|
|
|
|
|
|
|
|
le :: proc(r: ^Reader, n: int) -> u64 {
|
|
|
|
|
t := 0
|
|
|
|
|
|
|
|
|
|
for i in 0..<n {
|
|
|
|
|
byte := f(r, 8)
|
|
|
|
|
t += byte << (i * 8)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return t
|
|
|
|
|
}
|