// File: /workspace/github_cpp_makefile_star2_O3/mmoanis[P]mpegts_demux/MpegTsDemux.cpp
// Function: MpegTsDemuxer::ReadPES(unsigned char const*&, unsigned char const*, PacketHeader&, unsigned short)
bool MpegTsDemuxer::ReadPES(Packet::const_iterator &p, Packet::const_iterator e, PacketHeader& header, PID id)
{
    if (header.pusi) {
        /// PES PSI
        if (p[0] == 0x0 && p[1] == 0x0 && p[2] == 0x01) {
            p += 3;
            const uint8_t sidx = *p++;
            const bool video = MPEGTS_VIDEO_STREAM(sidx);
            const bool expected = MPEGTS_AUDIO_STREAM(sidx) || video;
            if (!expected) {
                cerr << "[ERROR]: PKT#" << m_pnum <<" Expected audio/video packets only. FOUND=" << hex << uint16_t(sidx) << dec << endl;
                return false;
            }

            Streams::iterator s = m_streams.find(id);
            if (s == m_streams.end()) {
                if (!RegisterStream(id, Program(), video))
                    return false;
                s = m_streams.find(id);
            }
            Stream* S = (*s).second;

            // escape packet length
            p += 2;

            // The rest of the header is of variable length.
            // but we know that there are at least 3 bytes. The third is the length of the optional fields followed by a byte that stores the
            p += 2;



            const uint8_t pl = *p++;
            if (p + pl >= e) {
                cerr << "[ERROR]: PKT#" << m_pnum <<" PES Invalid length." << m_pnum << endl;
                return false;
            }
            p += pl;

            // write to stream
            S->Write(p, e);
        } else {
            cerr << "[ERROR]: PKT#" << m_pnum <<" Expected PES start sequence." << endl;
            return false;
        }
    } else {
        Streams::iterator s = m_streams.find(id);
        if (s == m_streams.end()) {
            cerr << "[ERROR]: PKT#" << m_pnum <<" Invalid STREAM=" << id << endl;
            return false;
        }
        Stream* S = (*s).second;
        S->Write(p, e);
    }
    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x10, %rsp
movl %r8d, %ebp
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
cmpb $0x1, 0x1(%rcx)
jne 0x37cc
movq (%r15), %rax
cmpb $0x0, (%rax)
jne 0x3857
cmpb $0x0, 0x1(%rax)
jne 0x3857
cmpb $0x1, 0x2(%rax)
jne 0x3857
leaq 0x4(%rax), %rcx
movq %rcx, (%r15)
movb 0x3(%rax), %cl
movl %ecx, %eax
andb $-0x10, %al
cmpb $-0x20, %al
je 0x38e1
cmpb $-0x43, %cl
je 0x38e1
movl %ecx, %edx
andb $-0x20, %dl
cmpb $-0x40, %dl
je 0x38e1
movzbl %cl, %r14d
movq 0x4898(%rip), %r15      # 0x7ff0
leaq 0x1b13(%rip), %rsi      # 0x5272
movl $0xd, %edx
movq %r15, %rdi
callq 0x2160
movq 0x90(%rbx), %rsi
movq %r15, %rdi
callq 0x20b0
movq %rax, %rbx
leaq 0x1d46(%rip), %rsi      # 0x54cb
movl $0x2a, %edx
movq %rax, %rdi
callq 0x2160
movq (%rbx), %rax
movq -0x18(%rax), %rax
movl 0x18(%rbx,%rax), %ecx
andl $-0x4b, %ecx
orl $0x8, %ecx
movl %ecx, 0x18(%rbx,%rax)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x20b0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
jmp 0x39db
movq 0x40(%rbx), %rcx
testq %rcx, %rcx
je 0x3803
leaq 0x38(%rbx), %rdx
movq %rdx, %rax
xorl %esi, %esi
cmpw %bp, 0x20(%rcx)
setb %sil
cmovaeq %rcx, %rax
movq 0x10(%rcx,%rsi,8), %rcx
testq %rcx, %rcx
jne 0x37dc
cmpq %rdx, %rax
je 0x3803
cmpw %bp, 0x20(%rax)
jbe 0x38ce
movq 0x47e6(%rip), %r14      # 0x7ff0
leaq 0x1a61(%rip), %rsi      # 0x5272
movl $0xd, %edx
movq %r14, %rdi
callq 0x2160
movq 0x90(%rbx), %rsi
movq %r14, %rdi
callq 0x20b0
movq %rax, %rbx
leaq 0x1cf2(%rip), %rsi      # 0x5529
movl $0x10, %edx
movq %rax, %rdi
callq 0x2160
movzwl %bp, %esi
movq %rbx, %rdi
callq 0x20b0
movq %rax, %rbx
movq (%rax), %rax
jmp 0x389b
movq 0x4792(%rip), %r14      # 0x7ff0
leaq 0x1a0d(%rip), %rsi      # 0x5272
movl $0xd, %edx
movq %r14, %rdi
callq 0x2160
movq 0x90(%rbx), %rsi
movq %r14, %rdi
callq 0x20b0
movq %rax, %rbx
leaq 0x1c80(%rip), %rsi      # 0x550b
movl $0x1d, %edx
movq %rax, %rdi
callq 0x2160
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2120
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20c0
xorl %eax, %eax
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x28(%rax), %rdi
movq (%r15), %rsi
movq %r14, %rdx
callq 0x294e
movb $0x1, %al
jmp 0x38c1
movq 0x40(%rbx), %rdx
leaq 0x38(%rbx), %r12
testq %rdx, %rdx
je 0x3914
movq %r12, %rcx
xorl %esi, %esi
cmpw %bp, 0x20(%rdx)
setb %sil
cmovaeq %rdx, %rcx
movq 0x10(%rdx,%rsi,8), %rdx
testq %rdx, %rdx
jne 0x38f1
cmpq %r12, %rcx
je 0x3914
cmpw %bp, 0x20(%rcx)
jbe 0x3964
xorl %ecx, %ecx
cmpb $-0x20, %al
sete %cl
leaq 0xc(%rsp), %rdx
movl $0x1fff1fff, (%rdx)     # imm = 0x1FFF1FFF
movzwl %bp, %esi
movq %rbx, %rdi
callq 0x40de
movq 0x40(%rbx), %rcx
testq %rcx, %rcx
je 0x3961
movq %r12, %rax
xorl %edx, %edx
cmpw %bp, 0x20(%rcx)
setb %dl
cmovaeq %rcx, %rax
movq 0x10(%rcx,%rdx,8), %rcx
testq %rcx, %rcx
jne 0x393d
cmpq %r12, %rax
je 0x3961
cmpw %bp, 0x20(%rax)
cmovbeq %rax, %r12
movq %r12, %rcx
movq 0x28(%rcx), %rdi
movq (%r15), %rax
leaq 0x5(%rax), %rcx
movq %rcx, (%r15)
movzbl 0x4(%rax), %ecx
leaq (%rax,%rcx), %rsi
addq $0x5, %rsi
cmpq %r14, %rsi
jae 0x398b
movq %rsi, (%r15)
jmp 0x38d5
movq 0x465e(%rip), %r14      # 0x7ff0
leaq 0x18d9(%rip), %rsi      # 0x5272
movl $0xd, %edx
movq %r14, %rdi
callq 0x2160
movq 0x90(%rbx), %rsi
movq %r14, %rdi
callq 0x20b0
movq %rax, %r14
leaq 0x1b37(%rip), %rsi      # 0x54f6
movl $0x14, %edx
movq %rax, %rdi
callq 0x2160
movq 0x90(%rbx), %rsi
movq %r14, %rdi
callq 0x20b0
movq %rax, %rdi
callq 0x2090
jmp 0x38bf