// File: /workspace/github_cpp_makefile_star2_O2/lukasz-wiecaszek[P]h264iframedecoder/h264_parser.cpp
// Function: ymn::h264_parser::parse_slice_header(ymn::istream<0>&, unsigned int, unsigned int)
h264_parser_status_e h264_parser::parse_slice_header(istream_be& s, uint32_t nal_ref_idc, uint32_t nal_unit_type)
{
    h264_parser_status_e retval = h264_parser_status_e::NAL_UNIT_CORRUPTED;

    do {
        uint32_t pic_parameter_set_id;
        uint32_t seq_parameter_set_id;
        uint32_t slice_type;
        bool status;

        h264::slice_header& slice_header = m_slice_header;
        slice_header.reset();

        slice_header.nal_ref_idc = nal_ref_idc;
        slice_header.nal_unit_type = nal_unit_type;

        s.read_exp_golomb_u(slice_header.first_mb_in_slice);

        if (!CHK_EXPR(s.read_exp_golomb_u(slice_type), std::cout) ||
            !CHK_RANGE(slice_type, 0U, 9U, std::cout)) {
            s.mark_corrupted();
            break;
        }

        slice_header.slice_type = slice_type;

        if (!CHK_EXPR(s.read_exp_golomb_u(pic_parameter_set_id), std::cout) ||
            !CHK_RANGE(pic_parameter_set_id, 0U, static_cast<unsigned>(H264_PARSER_MAX_NUMBER_OF_PPS - 1), std::cout)) {
            s.mark_corrupted();
            break;
        }

        h264::pps& pps = m_pps_table[pic_parameter_set_id];
        if (!pps.is_valid()) {
            std::cout << "error: slice header refers to pps #" << pic_parameter_set_id << " which is not valid";
            std::cout << std::endl;
            break;
        }

        seq_parameter_set_id = pps.seq_parameter_set_id;

        h264::sps& sps = m_sps_table[seq_parameter_set_id];
        if (!sps.is_valid()) {
            std::cout << "error: pps #" << pic_parameter_set_id;
            std::cout << " refers to sps #" << seq_parameter_set_id << " which is not valid";
            std::cout << std::endl;
            break;
        }

        slice_header.pic_parameter_set_id = pic_parameter_set_id;
        slice_header.set_active_pps(&m_pps_table[pic_parameter_set_id]);

        if (sps.separate_colour_plane_flag)
            s.read_bits(2, slice_header.colour_plane_id);
        else
            slice_header.colour_plane_id = 3;//TODO: #define INVALID_COLOUR_PLANE_ID

        s.read_bits(sps.log2_max_frame_num_minus4 + 4, slice_header.frame_num);

        if (!sps.frame_mbs_only_flag) {
            s.read_bits(1, slice_header.field_pic_flag);
            if (slice_header.field_pic_flag)
                s.read_bits(1, slice_header.bottom_field_flag);
        }
        else
            slice_header.field_pic_flag = 0;

        if (nal_unit_type == 5)
            s.read_exp_golomb_u(slice_header.idr_pic_id);

        if (sps.pic_order_cnt_type == 0) {
            s.read_bits(sps.t0.log2_max_pic_order_cnt_lsb_minus4 + 4, slice_header.pic_order_cnt_lsb);
            if (pps.bottom_field_pic_order_in_frame_present_flag && !slice_header.field_pic_flag)
                s.read_exp_golomb_s(slice_header.delta_pic_order_cnt_bottom);
        }

        if (sps.pic_order_cnt_type == 1 && !sps.t1.delta_pic_order_always_zero_flag) {
            s.read_exp_golomb_s(slice_header.delta_pic_order_cnt[0]);
            if (pps.bottom_field_pic_order_in_frame_present_flag && !slice_header.field_pic_flag)
                s.read_exp_golomb_s(slice_header.delta_pic_order_cnt[1]);
        }

        if (pps.redundant_pic_cnt_present_flag)
            s.read_exp_golomb_u(slice_header.redundant_pic_cnt);

        if (h264::slice_type_e::B == slice_type)
            s.read_bits(1, slice_header.direct_spatial_mv_pred_flag);

        if (h264::slice_type_e::P  == slice_type ||
            h264::slice_type_e::SP == slice_type ||
            h264::slice_type_e::B  == slice_type) {
            s.read_bits(1, slice_header.num_ref_idx_active_override_flag);
            if (slice_header.num_ref_idx_active_override_flag) {
                if (!CHK_EXPR(s.read_exp_golomb_u(slice_header.num_ref_idx_l0_active_minus1), std::cout) ||
                    !CHK_STRUCT_RANGE(slice_header, num_ref_idx_l0_active_minus1, 0U, 31U, std::cout)) {
                    s.mark_corrupted();
                    break;
                }
                if (h264::slice_type_e::B == slice_type)
                    if (!CHK_EXPR(s.read_exp_golomb_u(slice_header.num_ref_idx_l1_active_minus1), std::cout) ||
                        !CHK_STRUCT_RANGE(slice_header, num_ref_idx_l1_active_minus1, 0U, 31U, std::cout)) {
                        s.mark_corrupted();
                        break;
                    }
            }
            else {
                slice_header.num_ref_idx_l0_active_minus1 = pps.num_ref_idx_l0_default_active_minus1;
                if (h264::slice_type_e::B == slice_type)
                    slice_header.num_ref_idx_l1_active_minus1 = pps.num_ref_idx_l1_default_active_minus1;
            }
        }

        if ((h264::slice_type_e::I != slice_type) &&
            (h264::slice_type_e::SI != slice_type)) {
            status = parse_ref_pic_list_modification(s, slice_header.rplm_l0);
            if (!status)
                break;
        }

        if (h264::slice_type_e::B == slice_type) {
            status = parse_ref_pic_list_modification(s, slice_header.rplm_l1);
            if (!status)
                break;
        }

        if ((pps.weighted_pred_flag && ((h264::slice_type_e::P == slice_type) || (h264::slice_type_e::SP == slice_type))) ||
            (pps.weighted_bipred_idc == 1 && (h264::slice_type_e::B == slice_type))) {
            h264::pred_weight_table& pwt = slice_header.pwt;

            pwt.slice_type = h264::to_slice_type_e(slice_type);
            pwt.chroma_components_present = sps.chroma_format_idc && !sps.separate_colour_plane_flag;
            pwt.num_ref_idx_l0_active_minus1 = slice_header.num_ref_idx_l0_active_minus1;
            pwt.num_ref_idx_l1_active_minus1 = slice_header.num_ref_idx_l1_active_minus1;

            status = parse_pred_weight_table(s, pwt);
            if (!status)
                break;
        }

        if (nal_ref_idc != 0) {
            if (nal_unit_type == 5)
                parse_dec_ref_pic_marking_idr(s, slice_header.drpm_idr);
            else
                parse_dec_ref_pic_marking_nonidr(s, slice_header.drpm_nonidr);
        }

        if ((pps.entropy_coding_mode_flag) &&
            (h264::slice_type_e::I != slice_type) && (h264::slice_type_e::SI != slice_type)) {
            if (!CHK_EXPR(s.read_exp_golomb_u(slice_header.cabac_init_idc), std::cout) ||
                !CHK_STRUCT_RANGE(slice_header, cabac_init_idc, 0U, 2U, std::cout)) {
                s.mark_corrupted();
                break;
            }
        }

        if (!CHK_EXPR(s.read_exp_golomb_s(slice_header.slice_qp_delta), std::cout) ||
            !CHK_STRUCT_RANGE(slice_header, slice_qp_delta,
                -26 - 6 * static_cast<int>(sps.bit_depth_luma_minus8) - pps.pic_init_qp_minus26,
                 25 - pps.pic_init_qp_minus26, std::cout)) {
            s.mark_corrupted();
            break;
        }

        if ((h264::slice_type_e::SI == slice_type) && (h264::slice_type_e::SP == slice_type)) {
            if (h264::slice_type_e::SP == slice_type)
                s.read_bits(1, slice_header.sp_for_switch_flag);
            s.read_exp_golomb_s(slice_header.slice_qs_delta);
        }

        if (pps.deblocking_filter_control_present_flag) {
            s.read_exp_golomb_u(slice_header.disable_deblocking_filter_idc);
            if (slice_header.disable_deblocking_filter_idc != 1) {
                s.read_exp_golomb_s(slice_header.slice_alpha_c0_offset_div2);
                s.read_exp_golomb_s(slice_header.slice_beta_offset_div2);
            }
        }

        if ((pps.num_slice_groups_minus1 > 0) &&
            ((pps.slice_group_map_type >= 3) && (pps.slice_group_map_type <= 5))) {
            s.read_bits(
                ilog2(pps.t2.slice_group_change_rate_minus1 + 1),
                slice_header.slice_group_change_cycle);
        }

        if (s.status() != ISTREAM_STATUS_OK)
            break;

        set_slice_data(s);

        slice_header.set_valid(true);
        retval = h264_parser_status_e::SLICE_PARSED;
    } while (0);

    return retval;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %ecx, %ebp
movl %edx, %r12d
movq %rsi, %r14
movq %rdi, %r15
movb $0x0, 0x87968(%rdi)
movl %edx, 0x8796c(%rdi)
movl %ecx, 0x87970(%rdi)
leaq 0x87974(%rdi), %rsi
movq %r14, %rdi
callq 0x6160
movq %rsp, %rsi
movq %r14, %rdi
callq 0x6160
movzbl %al, %esi
leaq 0xf575(%rip), %rdi      # 0x14a75
movq 0x18ab9(%rip), %rdx     # 0x1dfc0
callq 0x6109
pushq $0x2
popq %rbx
testb %al, %al
je 0x5b78
movl (%rsp), %esi
leaq 0xf169(%rip), %rdi      # 0x1468a
movq 0x18a98(%rip), %r8      # 0x1dfc0
pushq $0x9
popq %rcx
xorl %edx, %edx
callq 0x61f6
testb %al, %al
je 0x5b78
movl (%rsp), %eax
movl %eax, 0x87978(%r15)
leaq 0x4(%rsp), %rsi
movq %r14, %rdi
callq 0x6160
movzbl %al, %esi
leaq 0xf287(%rip), %rdi      # 0x147e2
movq 0x18a5e(%rip), %rdx     # 0x1dfc0
callq 0x6109
testb %al, %al
je 0x5b78
movl 0x4(%rsp), %esi
leaq 0xf0fb(%rip), %rdi      # 0x14675
movq 0x18a3f(%rip), %r8      # 0x1dfc0
xorl %edx, %edx
movl $0xff, %ecx
callq 0x61f6
testb %al, %al
je 0x5b78
movl 0x4(%rsp), %eax
imulq $0x718, %rax, %rcx      # imm = 0x718
cmpb $0x0, 0x16138(%r15,%rcx)
je 0x5609
leaq (%r15,%rcx), %rsi
addq $0x16130, %rsi          # imm = 0x16130
movl 0x10(%rsi), %r13d
imulq $0xb00, %r13, %rcx      # imm = 0xB00
cmpb $0x0, 0x130(%r15,%rcx)
je 0x5628
leaq (%r15,%rcx), %r13
addq $0x128, %r13            # imm = 0x128
movl %eax, 0x8797c(%r15)
movq %rsi, 0x882d8(%r15)
leaq 0x87980(%r15), %rdx
cmpl $0x0, 0x14(%r13)
movq %rsi, 0x10(%rsp)
je 0x5680
pushq $0x2
popq %rsi
movq %r14, %rdi
callq 0x5fee
jmp 0x5686
movq 0x189b0(%rip), %r14     # 0x1dfc0
leaq 0xf47e(%rip), %rsi      # 0x14a95
movq %r14, %rdi
callq 0x2120
movl 0x4(%rsp), %esi
movq %rax, %rdi
jmp 0x565f
movq 0x18991(%rip), %r14     # 0x1dfc0
leaq 0xf1d6(%rip), %rsi      # 0x1480c
movq %r14, %rdi
callq 0x2120
movl 0x4(%rsp), %esi
movq %rax, %rdi
callq 0x20e0
leaq 0xf1c8(%rip), %rsi      # 0x14819
movq %r14, %rdi
callq 0x2120
movq %rax, %rdi
movq %r13, %rsi
callq 0x20e0
leaq 0xf1bf(%rip), %rsi      # 0x1482a
movq %rax, %rdi
callq 0x2120
movq %r14, %rdi
callq 0x20b0
jmp 0x5b7d
movl $0x3, (%rdx)
movl 0x2d8(%r13), %esi
addl $0x4, %esi
leaq 0x87984(%r15), %rdx
movq %r14, %rdi
callq 0x5fee
movq %r13, %rax
leaq 0x87988(%r15), %r13
movq %rax, 0x8(%rsp)
cmpl $0x0, 0x6fc(%rax)
je 0x56be
andl $0x0, (%r13)
jmp 0x56e5
pushq $0x1
popq %rsi
movq %r14, %rdi
movq %r13, %rdx
callq 0x5fee
cmpl $0x0, (%r13)
je 0x56e5
leaq 0x8798c(%r15), %rdx
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0x5fee
cmpl $0x5, %ebp
movq 0x10(%rsp), %r13
jne 0x56fe
leaq 0x87990(%r15), %rsi
movq %r14, %rdi
callq 0x6160
movq 0x8(%rsp), %rax
movl 0x2dc(%rax), %eax
testl %eax, %eax
jne 0x5755
movq 0x8(%rsp), %rax
movl 0x2e0(%rax), %esi
addl $0x4, %esi
leaq 0x87994(%r15), %rdx
movq %r14, %rdi
callq 0x5fee
cmpl $0x0, 0x18(%r13)
je 0x574a
cmpl $0x0, 0x87988(%r15)
jne 0x574a
leaq 0x87998(%r15), %rsi
movq %r14, %rdi
callq 0x644a
movq 0x8(%rsp), %rax
movl 0x2dc(%rax), %eax
cmpl $0x1, %eax
jne 0x5797
movq 0x8(%rsp), %rax
cmpl $0x0, 0x2e0(%rax)
jne 0x5797
leaq 0x8799c(%r15), %rsi
movq %r14, %rdi
callq 0x644a
cmpl $0x0, 0x18(%r13)
je 0x5797
cmpl $0x0, 0x87988(%r15)
jne 0x5797
leaq 0x879a0(%r15), %rsi
movq %r14, %rdi
callq 0x644a
cmpl $0x0, 0x44c(%r13)
je 0x57b0
leaq 0x879a4(%r15), %rsi
movq %r14, %rdi
callq 0x6160
movl (%rsp), %ecx
pushq $0x5
popq %rsi
movl %ecx, %eax
xorl %edx, %edx
divl %esi
cmpl $0x1, %edx
jne 0x57df
leaq 0x879a8(%r15), %rdx
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0x5fee
movl (%rsp), %ecx
movl %ecx, %eax
xorl %edx, %edx
pushq $0x5
popq %rsi
divl %esi
cmpl $0x3, %edx
ja 0x590c
cmpl $0x2, %edx
je 0x590c
leaq 0x879ac(%r15), %rdx
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0x5fee
cmpl $0x0, 0x879ac(%r15)
je 0x58dd
leaq 0x879b0(%r15), %r13
movq %r14, %rdi
movq %r13, %rsi
callq 0x6160
movzbl %al, %esi
leaq 0xf28c(%rip), %rdi      # 0x14ab9
movq 0x1878c(%rip), %rdx     # 0x1dfc0
callq 0x6109
testb %al, %al
je 0x5b78
movl (%r13), %esi
leaq 0xf2ac(%rip), %rdi      # 0x14af8
movq 0x1876d(%rip), %r8      # 0x1dfc0
pushq $0x1f
popq %rcx
xorl %edx, %edx
callq 0x61f6
testb %al, %al
je 0x5b78
movl (%rsp), %ecx
movl %ecx, %eax
xorl %edx, %edx
pushq $0x5
popq %rsi
divl %esi
cmpl $0x1, %edx
jne 0x58d6
leaq 0x879b4(%r15), %r13
movq %r14, %rdi
movq %r13, %rsi
callq 0x6160
movzbl %al, %esi
leaq 0xf290(%rip), %rdi      # 0x14b22
movq 0x18727(%rip), %rdx     # 0x1dfc0
callq 0x6109
testb %al, %al
je 0x5b78
movl (%r13), %esi
leaq 0xf2b0(%rip), %rdi      # 0x14b61
movq 0x18708(%rip), %r8      # 0x1dfc0
pushq $0x1f
popq %rcx
xorl %edx, %edx
callq 0x61f6
testb %al, %al
je 0x5b78
movl (%rsp), %ecx
movl %ecx, %eax
xorl %edx, %edx
pushq $0x5
popq %rsi
divl %esi
movq 0x10(%rsp), %r13
jmp 0x590c
movl 0x428(%r13), %eax
movl %eax, 0x879b0(%r15)
movl (%rsp), %ecx
movl %ecx, %eax
xorl %edx, %edx
pushq $0x5
popq %rsi
divl %esi
cmpl $0x1, %edx
jne 0x590c
movl 0x42c(%r13), %eax
movl %eax, 0x879b4(%r15)
jmp 0x5916
cmpl $0x2, %edx
je 0x5930
cmpl $0x4, %edx
je 0x5930
leaq 0x879b8(%r15), %rdx
movq %r14, %rsi
callq 0x3f04
testb %al, %al
je 0x5b7d
movl (%rsp), %ecx
movl %ecx, %eax
xorl %edx, %edx
pushq $0x5
popq %rcx
divl %ecx
cmpl $0x1, %edx
jne 0x5955
leaq 0x879e8(%r15), %rdx
movq %r14, %rsi
callq 0x3f04
testb %al, %al
je 0x5b7d
cmpl $0x0, 0x430(%r13)
je 0x5974
movl (%rsp), %eax
xorl %edx, %edx
pushq $0x5
popq %rcx
divl %ecx
movl %edx, %eax
testl %edx, %edx
je 0x5990
cmpl $0x3, %eax
je 0x5990
cmpl $0x1, 0x434(%r13)
jne 0x59e7
movl (%rsp), %eax
xorl %edx, %edx
pushq $0x5
popq %rcx
divl %ecx
cmpl $0x1, %edx
jne 0x59e7
pushq $0x1
popq %rax
leaq 0x87a18(%r15), %rdx
movl %eax, 0x87a24(%r15)
movq 0x8(%rsp), %rax
cmpl $0x0, 0x10(%rax)
je 0x59b2
cmpl $0x0, 0x14(%rax)
sete %al
jmp 0x59b4
xorl %eax, %eax
movb %al, 0x87a28(%r15)
movl 0x879b0(%r15), %eax
movl 0x879b4(%r15), %ecx
movl %eax, 0x87a34(%r15)
movl %ecx, 0x87e38(%r15)
movq %r14, %rsi
callq 0x3fb8
testb %al, %al
je 0x5b7d
testl %r12d, %r12d
je 0x5a11
cmpl $0x5, %ebp
jne 0x5a02
leaq 0x88240(%r15), %rdx
movq %r14, %rsi
callq 0x4188
jmp 0x5a11
leaq 0x88258(%r15), %rdx
movq %r14, %rsi
callq 0x41c8
cmpl $0x0, 0x14(%r13)
je 0x5a30
movl (%rsp), %eax
xorl %edx, %edx
pushq $0x5
popq %rcx
divl %ecx
cmpl $0x2, %edx
je 0x5a30
cmpl $0x4, %edx
jne 0x5b28
leaq 0x882bc(%r15), %r12
movq %r14, %rdi
movq %r12, %rsi
callq 0x644a
movzbl %al, %esi
leaq 0xf18c(%rip), %rdi      # 0x14bd8
movq 0x1856d(%rip), %rdx     # 0x1dfc0
callq 0x6109
testb %al, %al
je 0x5b78
movl (%r12), %esi
movq 0x8(%rsp), %rax
imull $-0x6, 0x18(%rax), %edx
movl 0x438(%r13), %eax
subl %eax, %edx
addl $-0x1a, %edx
pushq $0x19
popq %rcx
subl %eax, %ecx
leaq 0xf184(%rip), %rdi      # 0x14c09
movq 0x18534(%rip), %r8      # 0x1dfc0
callq 0x64f5
testb %al, %al
je 0x5b78
cmpl $0x0, 0x444(%r13)
je 0x5ada
leaq 0x882c8(%r15), %rsi
movq %r14, %rdi
callq 0x6160
cmpl $0x1, 0x882c8(%r15)
je 0x5ada
leaq 0x882cc(%r15), %rsi
movq %r14, %rdi
callq 0x644a
leaq 0x882d0(%r15), %rsi
movq %r14, %rdi
callq 0x644a
cmpl $0x0, 0x1c(%r13)
je 0x5b09
movl 0x20(%r13), %eax
addl $-0x3, %eax
cmpl $0x2, %eax
ja 0x5b09
movl 0x28(%r13), %edi
incl %edi
callq 0x5b8e
leaq 0x882d4(%r15), %rdx
movq %r14, %rdi
movl %eax, %esi
callq 0x5fee
cmpl $0x0, 0x20(%r14)
jne 0x5b7d
movq %r15, %rdi
movq %r14, %rsi
callq 0x5d46
movb $0x1, 0x87968(%r15)
pushq $0x7
popq %rbx
jmp 0x5b7d
leaq 0x882b8(%r15), %r12
movq %r14, %rdi
movq %r12, %rsi
callq 0x6160
movzbl %al, %esi
leaq 0xf047(%rip), %rdi      # 0x14b8b
movq 0x18475(%rip), %rdx     # 0x1dfc0
callq 0x6109
testb %al, %al
je 0x5b78
movl (%r12), %esi
leaq 0xf05d(%rip), %rdi      # 0x14bbc
movq 0x1845a(%rip), %r8      # 0x1dfc0
pushq $0x2
popq %rcx
xorl %edx, %edx
callq 0x61f6
testb %al, %al
jne 0x5a30
orb $0x4, 0x20(%r14)
movl %ebx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq