// File: /workspace/github_cpp_makefile_star2_O2/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
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
movw %r8w, 0x2(%rsp)
cmpb $0x1, 0x1(%rcx)
jne 0x329e
movq (%r15), %rax
cmpb $0x0, (%rax)
jne 0x32c8
cmpb $0x0, 0x1(%rax)
jne 0x32c8
cmpb $0x1, 0x2(%rax)
jne 0x32c8
leaq 0x4(%rax), %rcx
movq %rcx, (%r15)
movb 0x3(%rax), %al
movl %eax, %ebp
andb $-0x10, %bpl
cmpb $-0x20, %bpl
je 0x3352
cmpb $-0x43, %al
je 0x3352
movl %eax, %ecx
andb $-0x20, %cl
cmpb $-0x40, %cl
je 0x3352
movzbl %al, %ebp
movq 0x4db6(%rip), %rdi      # 0x7ff0
leaq 0x2031(%rip), %rsi      # 0x5272
callq 0x2110
movq 0x90(%rbx), %rsi
movq %rax, %rdi
callq 0x20a0
leaq 0x226f(%rip), %rsi      # 0x54cb
movq %rax, %rdi
callq 0x2110
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x8, %edx
movl %edx, 0x18(%rax,%rcx)
movzwl %bp, %esi
movq %rax, %rdi
callq 0x21d0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
jmp 0x3339
leaq 0x30(%rbx), %rdi
leaq 0x2(%rsp), %rsi
callq 0x3ec2
leaq 0x38(%rbx), %rcx
cmpq %rcx, %rax
je 0x32fb
movq 0x28(%rax), %rdi
movq (%r15), %rsi
movq %r14, %rdx
callq 0x2772
movb $0x1, %al
jmp 0x3343
movq 0x4d21(%rip), %rdi      # 0x7ff0
leaq 0x1f9c(%rip), %rsi      # 0x5272
callq 0x2110
movq 0x90(%rbx), %rsi
movq %rax, %rdi
callq 0x20a0
leaq 0x221a(%rip), %rsi      # 0x550b
movq %rax, %rdi
callq 0x2110
jmp 0x3339
movq 0x4cee(%rip), %rdi      # 0x7ff0
leaq 0x1f69(%rip), %rsi      # 0x5272
callq 0x2110
movq 0x90(%rbx), %rsi
movq %rax, %rdi
callq 0x20a0
leaq 0x2205(%rip), %rsi      # 0x5529
movq %rax, %rdi
callq 0x2110
movzwl 0x2(%rsp), %esi
movq %rax, %rdi
callq 0x21d0
movq %rax, %rdi
callq 0x2080
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x30(%rbx), %r12
leaq 0x2(%rsp), %rsi
movq %r12, %rdi
callq 0x3ec2
leaq 0x38(%rbx), %rcx
cmpq %rcx, %rax
jne 0x339d
xorl %ecx, %ecx
cmpb $-0x20, %bpl
sete %cl
leaq 0x2(%rsp), %r13
movzwl (%r13), %esi
leaq 0x4(%rsp), %rdx
movl $0x1fff1fff, (%rdx)     # imm = 0x1FFF1FFF
movq %rbx, %rdi
callq 0x38d4
movq %r12, %rdi
movq %r13, %rsi
callq 0x3ec2
movq 0x28(%rax), %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 0x33c4
movq %rsi, (%r15)
jmp 0x32bc
movq 0x4c25(%rip), %rdi      # 0x7ff0
leaq 0x1ea0(%rip), %rsi      # 0x5272
callq 0x2110
movq 0x90(%rbx), %rsi
movq %rax, %rdi
callq 0x20a0
leaq 0x2109(%rip), %rsi      # 0x54f6
movq %rax, %rdi
callq 0x2110
movq 0x90(%rbx), %rsi
movq %rax, %rdi
callq 0x20a0
jmp 0x3339
nop