// File: lukasz-wiecaszek[P]h264iframedecoder/h264_decoder.cpp
// Function: ymn::h264_decoder::parse()
void h264_decoder::parse()
{
    h264_parser_status_e status;

    do {
        status = m_parser.parse();

        switch (status) {
            case h264_parser_status_e::NAL_UNIT_SKIPPED:
                break;

            case h264_parser_status_e::NAL_UNIT_CORRUPTED:
                break;

            case h264_parser_status_e::AUD_PARSED:
            {
                const h264_structure* aud;

                aud = m_parser.get_structure(
                    h264_parser_structure_e::AUD,
                    H264_PARSER_STRUCTURE_ID_RECENT);

                if (aud)
                    std::cout << aud->to_string();
                else
                    std::cout << "Parser returned '" << ymn::to_string(status) <<
                        "' but associated structure cannot be retrived" << std::endl;
                break;
            }

            case h264_parser_status_e::SPS_PARSED:
            {
                const h264_structure* sps;

                sps = m_parser.get_structure(
                    h264_parser_structure_e::SPS,
                    H264_PARSER_STRUCTURE_ID_RECENT);

                if (sps)
                    std::cout << sps->to_string();
                else
                    std::cout << "Parser returned '" << ymn::to_string(status) <<
                        "' but associated structure cannot be retrived" << std::endl;
                break;
            }

            case h264_parser_status_e::PPS_PARSED:
            {
                const h264_structure* pps;

                pps = m_parser.get_structure(
                    h264_parser_structure_e::PPS,
                    H264_PARSER_STRUCTURE_ID_RECENT);

                if (pps)
                    std::cout << pps->to_string();
                else
                    std::cout << "Parser returned '" << ymn::to_string(status) <<
                        "' but associated structure cannot be retrived" << std::endl;
                break;
            }

            case h264_parser_status_e::SEI_PARSED:
            {
                const h264_structure* sei;

                sei = m_parser.get_structure(
                    h264_parser_structure_e::SEI,
                    H264_PARSER_STRUCTURE_ID_RECENT);

                if (sei)
                    std::cout << sei->to_string();
                else
                    std::cout << "Parser returned '" << ymn::to_string(status) <<
                        "' but associated structure cannot be retrived" << std::endl;
                break;
            }

            case h264_parser_status_e::SLICE_PARSED:
            {
                const h264_structure* slice_header;

                slice_header = m_parser.get_structure(
                    h264_parser_structure_e::SLICE_HEADER,
                    H264_PARSER_STRUCTURE_ID_RECENT);

                if (slice_header)
                    std::cout << slice_header->to_string();
                else
                    std::cout << "Parser returned '" << ymn::to_string(status) <<
                        "' but associated structure cannot be retrived" << std::endl;

                const h264_structure* slice_data;

                slice_data = m_parser.get_structure(
                    h264_parser_structure_e::SLICE_DATA,
                    H264_PARSER_STRUCTURE_ID_RECENT);

                if (slice_data)
                    std::cout << slice_data->to_string();
                else
                    std::cout << "Parser returned '" << ymn::to_string(status) <<
                        "' but associated structure cannot be retrived" << std::endl;

                if (slice_header && slice_data)
                    decode_slice(
                        *reinterpret_cast<const h264::slice_header*>(slice_header),
                        *reinterpret_cast<const h264::slice_data*>(slice_data));
                break;
            }

            default:
                break;
       }
    } while (status != h264_parser_status_e::NEED_BYTES);
}

// Assembly:
subq $0x148, %rsp            # imm = 0x148
movq %rdi, 0x140(%rsp)
movq 0x140(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rdi
callq 0x1b6a0
movl %eax, 0x13c(%rsp)
movl 0x13c(%rsp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, 0x38(%rsp)
subl $0x6, %eax
ja 0x1a4ab
movq 0x38(%rsp), %rax
leaq 0xdf72(%rip), %rcx      # 0x27fd4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0x1a4ad
jmp 0x1a4ad
movq 0x40(%rsp), %rdi
xorl %esi, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x12300
movq %rax, 0x130(%rsp)
cmpq $0x0, 0x130(%rsp)
je 0x1a0d1
movq 0x130(%rsp), %rsi
movq (%rsi), %rax
leaq 0x110(%rsp), %rdi
callq *(%rax)
movq 0x13f0b(%rip), %rdi     # 0x2dfc0
leaq 0x110(%rsp), %rsi
callq 0x2130
leaq 0x110(%rsp), %rdi
callq 0x20e0
jmp 0x1a120
movq 0x13ee8(%rip), %rdi     # 0x2dfc0
leaq 0xe051(%rip), %rsi      # 0x28130
callq 0x2140
movq %rax, 0x30(%rsp)
movl 0x13c(%rsp), %edi
callq 0x1ae50
movq 0x30(%rsp), %rdi
movq %rax, %rsi
callq 0x2140
movq %rax, %rdi
leaq 0xe036(%rip), %rsi      # 0x28142
callq 0x2140
movq %rax, %rdi
movq 0x13e8d(%rip), %rsi     # 0x2dfa8
callq 0x2180
jmp 0x1a4ad
movq 0x40(%rsp), %rdi
movl $0x1, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x12300
movq %rax, 0x108(%rsp)
cmpq $0x0, 0x108(%rsp)
je 0x1a184
movq 0x108(%rsp), %rsi
movq (%rsi), %rax
leaq 0xe8(%rsp), %rdi
callq *(%rax)
movq 0x13e58(%rip), %rdi     # 0x2dfc0
leaq 0xe8(%rsp), %rsi
callq 0x2130
leaq 0xe8(%rsp), %rdi
callq 0x20e0
jmp 0x1a1d3
movq 0x13e35(%rip), %rdi     # 0x2dfc0
leaq 0xdf9e(%rip), %rsi      # 0x28130
callq 0x2140
movq %rax, 0x28(%rsp)
movl 0x13c(%rsp), %edi
callq 0x1ae50
movq 0x28(%rsp), %rdi
movq %rax, %rsi
callq 0x2140
movq %rax, %rdi
leaq 0xdf83(%rip), %rsi      # 0x28142
callq 0x2140
movq %rax, %rdi
movq 0x13dda(%rip), %rsi     # 0x2dfa8
callq 0x2180
jmp 0x1a4ad
movq 0x40(%rsp), %rdi
movl $0x2, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x12300
movq %rax, 0xe0(%rsp)
cmpq $0x0, 0xe0(%rsp)
je 0x1a237
movq 0xe0(%rsp), %rsi
movq (%rsi), %rax
leaq 0xc0(%rsp), %rdi
callq *(%rax)
movq 0x13da5(%rip), %rdi     # 0x2dfc0
leaq 0xc0(%rsp), %rsi
callq 0x2130
leaq 0xc0(%rsp), %rdi
callq 0x20e0
jmp 0x1a286
movq 0x13d82(%rip), %rdi     # 0x2dfc0
leaq 0xdeeb(%rip), %rsi      # 0x28130
callq 0x2140
movq %rax, 0x20(%rsp)
movl 0x13c(%rsp), %edi
callq 0x1ae50
movq 0x20(%rsp), %rdi
movq %rax, %rsi
callq 0x2140
movq %rax, %rdi
leaq 0xded0(%rip), %rsi      # 0x28142
callq 0x2140
movq %rax, %rdi
movq 0x13d27(%rip), %rsi     # 0x2dfa8
callq 0x2180
jmp 0x1a4ad
movq 0x40(%rsp), %rdi
movl $0x3, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x12300
movq %rax, 0xb8(%rsp)
cmpq $0x0, 0xb8(%rsp)
je 0x1a2ea
movq 0xb8(%rsp), %rsi
movq (%rsi), %rax
leaq 0x98(%rsp), %rdi
callq *(%rax)
movq 0x13cf2(%rip), %rdi     # 0x2dfc0
leaq 0x98(%rsp), %rsi
callq 0x2130
leaq 0x98(%rsp), %rdi
callq 0x20e0
jmp 0x1a339
movq 0x13ccf(%rip), %rdi     # 0x2dfc0
leaq 0xde38(%rip), %rsi      # 0x28130
callq 0x2140
movq %rax, 0x18(%rsp)
movl 0x13c(%rsp), %edi
callq 0x1ae50
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0x2140
movq %rax, %rdi
leaq 0xde1d(%rip), %rsi      # 0x28142
callq 0x2140
movq %rax, %rdi
movq 0x13c74(%rip), %rsi     # 0x2dfa8
callq 0x2180
jmp 0x1a4ad
movq 0x40(%rsp), %rdi
movl $0x4, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x12300
movq %rax, 0x90(%rsp)
cmpq $0x0, 0x90(%rsp)
je 0x1a394
movq 0x90(%rsp), %rsi
movq (%rsi), %rax
leaq 0x70(%rsp), %rdi
callq *(%rax)
movq 0x13c42(%rip), %rdi     # 0x2dfc0
leaq 0x70(%rsp), %rsi
callq 0x2130
leaq 0x70(%rsp), %rdi
callq 0x20e0
jmp 0x1a3e3
movq 0x13c25(%rip), %rdi     # 0x2dfc0
leaq 0xdd8e(%rip), %rsi      # 0x28130
callq 0x2140
movq %rax, 0x10(%rsp)
movl 0x13c(%rsp), %edi
callq 0x1ae50
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0x2140
movq %rax, %rdi
leaq 0xdd73(%rip), %rsi      # 0x28142
callq 0x2140
movq %rax, %rdi
movq 0x13bca(%rip), %rsi     # 0x2dfa8
callq 0x2180
movq 0x40(%rsp), %rdi
movl $0x5, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x12300
movq %rax, 0x68(%rsp)
cmpq $0x0, 0x68(%rsp)
je 0x1a430
movq 0x68(%rsp), %rsi
movq (%rsi), %rax
leaq 0x48(%rsp), %rdi
callq *(%rax)
movq 0x13ba6(%rip), %rdi     # 0x2dfc0
leaq 0x48(%rsp), %rsi
callq 0x2130
leaq 0x48(%rsp), %rdi
callq 0x20e0
jmp 0x1a47f
movq 0x13b89(%rip), %rdi     # 0x2dfc0
leaq 0xdcf2(%rip), %rsi      # 0x28130
callq 0x2140
movq %rax, 0x8(%rsp)
movl 0x13c(%rsp), %edi
callq 0x1ae50
movq 0x8(%rsp), %rdi
movq %rax, %rsi
callq 0x2140
movq %rax, %rdi
leaq 0xdcd7(%rip), %rsi      # 0x28142
callq 0x2140
movq %rax, %rdi
movq 0x13b2e(%rip), %rsi     # 0x2dfa8
callq 0x2180
cmpq $0x0, 0x90(%rsp)
je 0x1a4a9
cmpq $0x0, 0x68(%rsp)
je 0x1a4a9
movq 0x40(%rsp), %rdi
movq 0x90(%rsp), %rsi
movq 0x68(%rsp), %rdx
callq 0x1abe0
jmp 0x1a4ad
jmp 0x1a4ad
jmp 0x1a4af
cmpl $0x0, 0x13c(%rsp)
jne 0x1a02c
addq $0x148, %rsp            # imm = 0x148
retq
nopw %cs:(%rax,%rax)