// File: /workspace/github_cpp_makefile_star2_O1/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 %r13
pushq %r12
pushq %rbx
pushq %rax
movl %r8d, %ebp
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
cmpb $0x1, 0x1(%rcx)
jne 0x3883
movq (%r15), %rax
cmpb $0x0, (%rax)
jne 0x38dd
cmpb $0x0, 0x1(%rax)
jne 0x38dd
cmpb $0x1, 0x2(%rax)
jne 0x38dd
leaq 0x4(%rax), %rcx
movq %rcx, (%r15)
movb 0x3(%rax), %cl
movl %ecx, %eax
andb $-0x10, %al
cmpb $-0x20, %al
je 0x39d0
cmpb $-0x43, %cl
je 0x39d0
movl %ecx, %edx
andb $-0x20, %dl
cmpb $-0x40, %dl
je 0x39d0
movzbl %cl, %r14d
movq 0x47e1(%rip), %r15      # 0x7ff0
leaq 0x1a60(%rip), %rsi      # 0x5276
movl $0xd, %edx
movq %r15, %rdi
callq 0x2170
movq 0x90(%rbx), %rsi
movq %r15, %rdi
callq 0x20c0
movq %rax, %rbx
leaq 0x1c93(%rip), %rsi      # 0x54cf
movl $0x2a, %edx
movq %rax, %rdi
callq 0x2170
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 0x20c0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
jmp 0x3ae5
movq 0x40(%rbx), %rcx
leaq 0x38(%rbx), %r12
movq %r12, %rax
testq %rcx, %rcx
je 0x38ad
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 0x3896
movq %r12, %r13
cmpq %r12, %rax
je 0x38c0
cmpw %bp, 0x20(%rax)
cmovaq %r12, %rax
movq %rax, %r13
cmpq %r12, %r13
je 0x394a
movq 0x28(%r13), %rdi
movq (%r15), %rsi
movq %r14, %rdx
callq 0x2962
jmp 0x39c0
movq 0x470c(%rip), %r14      # 0x7ff0
leaq 0x198b(%rip), %rsi      # 0x5276
movl $0xd, %edx
movq %r14, %rdi
callq 0x2170
movq 0x90(%rbx), %rsi
movq %r14, %rdi
callq 0x20c0
movq %rax, %rbx
leaq 0x1bfe(%rip), %rsi      # 0x550f
movl $0x1d, %edx
movq %rax, %rdi
callq 0x2170
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2130
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20d0
jmp 0x3aed
movq 0x469f(%rip), %r14      # 0x7ff0
leaq 0x191e(%rip), %rsi      # 0x5276
movl $0xd, %edx
movq %r14, %rdi
callq 0x2170
movq 0x90(%rbx), %rsi
movq %r14, %rdi
callq 0x20c0
movq %rax, %rbx
leaq 0x1baf(%rip), %rsi      # 0x552d
movl $0x10, %edx
movq %rax, %rdi
callq 0x2170
movzwl %bp, %esi
movq %rbx, %rdi
callq 0x20c0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2130
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20d0
cmpq %r12, %r13
je 0x3aed
movb $0x1, %al
jmp 0x3aef
movq 0x40(%rbx), %rdx
leaq 0x38(%rbx), %r12
movq %r12, %rcx
testq %rdx, %rdx
je 0x39fb
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 0x39e3
movq %r12, %rdx
cmpq %r12, %rcx
je 0x3a0e
cmpw %bp, 0x20(%rcx)
cmovaq %r12, %rcx
movq %rcx, %rdx
cmpq %r12, %rdx
jne 0x3a66
xorl %ecx, %ecx
cmpb $-0x20, %al
sete %cl
leaq 0x4(%rsp), %rdx
movl $0x1fff1fff, (%rdx)     # imm = 0x1FFF1FFF
movzwl %bp, %esi
movq %rbx, %rdi
callq 0x4278
movq 0x40(%rbx), %rcx
movq %r12, %rax
testq %rcx, %rcx
je 0x3a56
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 0x3a3f
cmpq %r12, %rax
je 0x3a63
cmpw %bp, 0x20(%rax)
cmovbeq %rax, %r12
movq %r12, %rdx
movq 0x28(%rdx), %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 0x3a95
movq %rsi, (%r15)
movq %r14, %rdx
callq 0x2962
jmp 0x39c9
movq 0x4554(%rip), %r14      # 0x7ff0
leaq 0x17d3(%rip), %rsi      # 0x5276
movl $0xd, %edx
movq %r14, %rdi
callq 0x2170
movq 0x90(%rbx), %rsi
movq %r14, %rdi
callq 0x20c0
movq %rax, %r14
leaq 0x1a31(%rip), %rsi      # 0x54fa
movl $0x14, %edx
movq %rax, %rdi
callq 0x2170
movq 0x90(%rbx), %rsi
movq %r14, %rdi
callq 0x20c0
movq %rax, %rdi
callq 0x20a0
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq