// File: /workspace/github_cpp_makefile_star2_O1/cpearce[P]OggIndex/src/Decoder.cpp
// Function: TheoraDecoder::Decode(ogg_page*, long)
bool Decode(ogg_page* page, ogg_int64_t offset) {
    assert((ogg_uint32_t)ogg_page_serialno(page) == mSerial);
    if (GotAllHeaders()) {
      Page record;
      record.num_packets = CountPacketStarts(page);
      record.offset = offset;
      mPages.push_back(record);
    }
 
    int ret = ogg_stream_pagein(&mState, page);
    ogg_int64_t page_granulepos = ogg_page_granulepos(page);
    assert(ret == 0);

    ogg_packet packet;
    int num_packets = 0;
    vector<Frame> frames;
    while ((ret = ogg_stream_packetout(&mState, &packet)) != 0) {
      if (ret == -1) {
        cerr << "WARNING: Lost sync decoding packets on theora page "
             << mPages.size() << endl;
        continue;
      }
      num_packets++;
      if (!GotAllHeaders()) {
        // Read Headers...
        ret = th_decode_headerin(&mInfo,
                                 &mComment,
                                 &mSetup,
                                 &packet);
        assert(ret > 0);
        if (ret > 0) {
          // Read Theora header.
          mHeadersRead++;
        }
        if (GotAllHeaders()) {
          // Read all headers, setup decoder context.
          mCtx = th_decode_alloc(&mInfo, mSetup);
          assert(mCtx != NULL);
        }
        if (gOptions.GetDumpPackets()) {
          cout << "[T] ver="
               << (int)mInfo.version_major << "."
               << (int)mInfo.version_minor << "."
               << (int)mInfo.version_subminor << " "
               << TheoraHeaderType(&packet) << " packet"
               << (packet.e_o_s ? " eos" : "")
               << endl;
        }
        continue;
      }      

      if (mFirstPacketno == -1) {
        mFirstPacketno = packet.packetno;
      }
      
      const int shift = mInfo.keyframe_granule_shift;

      // Packet should only have a granulepos if the page does.
      assert(page_granulepos != -1 || packet.granulepos == -1);
      assert(packet.granulepos == -1 || packet.granulepos == page_granulepos);
      
      // We've not yet determined the granulepos of the first (or previous)
      // packet. Remember the packet, even if it's not a keyframe so that
      // we can backtrack to get all packets' start time.
      frames.push_back(Frame(packet));

      if (packet.granulepos == -1) {
        // We've stored the packet, once we find one with a non -1 granulepos
        // we can find the first packet's granulepos.
        continue;
      }
        
      // We know a packet's granulepos, use it to tag the packets buffered
      // before it so that they have valid granulepos.
      for (int i=(int)frames.size()-2; i>=0; i--) {
        ogg_int64_t prev_granulepos = frames[i+1].granulepos;
        assert(prev_granulepos != -1);
        ogg_int64_t granulepos = -1;
        if (frames[i].is_keyframe) {
          ogg_int64_t frame = th_granule_frame(mCtx, prev_granulepos) +
                              TheoraVersion(&mInfo,3,2,1) - 1;
          // 3.2.0 streams store the frame index in the granule position.
          // 3.2.1 and later store the frame count. th_granule_frame() returns
          // the frame index, so |frame| can be 0 when we're theora version
          // 3.2.0 or less.
          assert(frame > 0 || !TheoraVersion(&mInfo,3,2,1));
          granulepos = frame << shift;
        } else {
          if (frames[i+1].is_keyframe) {
            // The successor frame is a keyframe, so we can't just subtract 1
            // from the "keyframe offset" part of its granulepos, as it
            // doesn't have one! So fake it, take the keyframe offset as the
            // max possible keyframe offset. This means the granulepos (probably)
            // overshoots and claims that it depends on a frame before its actual
            // keyframe but at least its granule number will be correct, so the
            // times we calculate from this granulepos will also be correct.
            ogg_int64_t frameno = th_granule_frame(mCtx, prev_granulepos);
            ogg_int64_t max_offset = min((frameno - 1),
                                          (ogg_int64_t)(1 << shift) - 1);
            ogg_int64_t granule = frameno +
                                  TheoraVersion(&mInfo,3,2,1) -
                                  1 - max_offset;
            assert(granule > 0); // We must have positive granulepos...
            granulepos = (granule << shift) + max_offset;
          } else {
            // We must be offset by more than 1 frame for this to work.
            assert((prev_granulepos & ((1 << shift) - 1)) > 0);
            granulepos = prev_granulepos - 1;
          }
        }
        // This frame's granule number should be one less than the previous.
        assert(th_granule_frame(mCtx, granulepos) ==
                th_granule_frame(mCtx, prev_granulepos) - 1);
        frames[i].granulepos = granulepos;
      }
      // Now all packets have a known time.
      if (mStartTime == -1) {
        mStartTime = StartTime(frames.front().granulepos);
      }
      assert(mStartTime >= 0);
      mEndTime = EndTime(frames.back().granulepos);
      assert(mEndTime >= mStartTime);

      // Print/log packets before we remove non-keyframe packets.
      for (unsigned i=0; i<frames.size(); i++) {
        DumpPacket(frames[i]);
      }

      // Add keyframes to the final frame list.
      for (unsigned i=0; i<frames.size(); i++) {
        if (frames[i].is_keyframe) {
          mFrames.push_back(frames[i]);
        }
      }
    } // end while packetout


    if (num_packets != ogg_page_packets(page)) {
      cerr << "WARNING: Fewer packets finished on theora page "
           << mPages.size() << " than expected." << endl;
    }
    return true;
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x42d0
cmpl 0x1a0(%rbx), %eax
jne 0x6116
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x18(%rax)
testb %al, %al
je 0x591b
movq %r15, %rdi
callq 0xcad7
movl %eax, 0x40(%rsp)
movq %r14, 0x38(%rsp)
movq 0x250(%rbx), %rsi
cmpq 0x258(%rbx), %rsi
je 0x590a
movups 0x38(%rsp), %xmm0
movups %xmm0, (%rsi)
addq $0x10, 0x250(%rbx)
jmp 0x591b
leaq 0x248(%rbx), %rdi
leaq 0x38(%rsp), %rdx
callq 0x67c0
leaq 0x8(%rbx), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0x4550
movl %eax, %ebp
movq %r15, %rdi
callq 0x4620
testl %ebp, %ebp
jne 0x6135
movq %rax, %r13
xorps %xmm0, %xmm0
movq %rsp, %rax
movaps %xmm0, (%rax)
movq $0x0, 0x10(%rax)
leaq 0x1b8(%rbx), %rax
movq %rax, 0x18(%rsp)
leaq 0x1f8(%rbx), %rax
movq %rax, 0xa8(%rsp)
leaq 0x218(%rbx), %rax
movq %rax, 0x30(%rsp)
leaq 0x260(%rbx), %rax
movq %rax, 0xb0(%rsp)
movq $0x0, 0x20(%rsp)
leaq 0x38(%rsp), %rbp
movq %r12, %rdi
movq %rbp, %rsi
callq 0x45a0
cmpl $-0x1, %eax
jne 0x5a06
movl $0x33, %edx
movq 0x11640(%rip), %rdi     # 0x16ff0
leaq 0xa9d8(%rip), %rsi      # 0x1038f
callq 0x4410
movq 0x250(%rbx), %rsi
subq 0x248(%rbx), %rsi
sarq $0x4, %rsi
movq 0x1161b(%rip), %rdi     # 0x16ff0
callq 0x4240
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x4360
movsbl %al, %esi
movq %r14, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x4250
jmp 0x5994
testl %eax, %eax
je 0x5fcf
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x18(%rax)
movq 0x20(%rsp), %rcx
incl %ecx
movq %rcx, 0x20(%rsp)
testb %al, %al
je 0x5ad1
cmpq $-0x1, 0x240(%rbx)
jne 0x5a41
movq 0x60(%rsp), %rax
movq %rax, 0x240(%rbx)
cmpq $-0x1, %r13
setne %cl
movq 0x58(%rsp), %rax
cmpq $-0x1, %rax
sete %dl
orb %cl, %dl
je 0x6173
cmpq $-0x1, %rax
sete %cl
cmpq %r13, %rax
sete %dl
orb %cl, %dl
je 0x6192
movl 0x1f4(%rbx), %ecx
movq %rcx, 0x28(%rsp)
movq 0x60(%rsp), %rcx
movq %rcx, 0x68(%rsp)
movq %rax, 0x70(%rsp)
movq %rbp, %rdi
callq 0x42a0
testl %eax, %eax
setne 0x78(%rsp)
cmpq $0x0, 0x50(%rsp)
setne 0x79(%rsp)
movq 0x8(%rsp), %rsi
cmpq 0x10(%rsp), %rsi
je 0x5c75
movq 0x78(%rsp), %rax
movq %rax, 0x10(%rsi)
movups 0x68(%rsp), %xmm0
movups %xmm0, (%rsi)
addq $0x18, 0x8(%rsp)
jmp 0x5c82
movq 0x18(%rsp), %rdi
movq 0xa8(%rsp), %rsi
movq 0x30(%rsp), %rdx
movq %rbp, %rcx
callq 0x4600
testl %eax, %eax
jle 0x6154
incl 0x228(%rbx)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x18(%rax)
testb %al, %al
je 0x5b28
movq 0x30(%rsp), %rax
movq (%rax), %rsi
movq 0x18(%rsp), %rdi
callq 0x4440
movq %rax, 0x220(%rbx)
testq %rax, %rax
je 0x61ef
leaq 0x118f1(%rip), %rdi     # 0x17420
callq 0x8c4e
testb %al, %al
je 0x5994
movl $0x8, %edx
movq 0x11488(%rip), %rdi     # 0x16fd0
leaq 0xa889(%rip), %rsi      # 0x103d8
callq 0x4410
movq 0x18(%rsp), %rax
movzbl (%rax), %esi
movq 0x1146d(%rip), %rdi     # 0x16fd0
callq 0x46a0
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0xaff3(%rip), %rsi      # 0x10b6d
callq 0x4410
movzbl 0x1b9(%rbx), %esi
movq %r14, %rdi
callq 0x46a0
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0xafcd(%rip), %rsi      # 0x10b6d
callq 0x4410
movzbl 0x1ba(%rbx), %esi
movq %r14, %rdi
callq 0x46a0
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0xba12(%rip), %rsi      # 0x115d8
callq 0x4410
movq 0x38(%rsp), %rax
movzbl (%rax), %eax
xorq $0x80, %rax
leaq 0xa9dd(%rip), %rbp      # 0x105bd
cmpb $0x2, %al
ja 0x5bf2
leaq 0xac79(%rip), %rcx      # 0x10864
movslq (%rcx,%rax,4), %rbp
addq %rcx, %rbp
movq %rbp, %rdi
callq 0x4170
movq %r14, %rdi
movq %rbp, %rsi
movq %rax, %rdx
callq 0x4410
leaq 0x38(%rsp), %rbp
movl $0x7, %edx
movq %r14, %rdi
leaq 0xa7c5(%rip), %rsi      # 0x103e1
callq 0x4410
xorl %edx, %edx
cmpq $0x0, 0x50(%rsp)
setne %dl
leaq 0xa7b6(%rip), %rsi      # 0x103e9
leaq 0xb7f0(%rip), %rax      # 0x1142a
cmoveq %rax, %rsi
shll $0x2, %edx
movq %r14, %rdi
callq 0x4410
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x4360
movsbl %al, %esi
movq %r14, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x4250
jmp 0x5994
movq %rsp, %rdi
leaq 0x68(%rsp), %rdx
callq 0x6900
cmpq $-0x1, 0x58(%rsp)
je 0x5994
movq %r13, 0x80(%rsp)
movq %r12, 0x88(%rsp)
movq %r15, 0x90(%rsp)
movq 0x8(%rsp), %rax
subq (%rsp), %rax
shrq $0x3, %rax
imull $0xaaaaaaab, %eax, %r13d # imm = 0xAAAAAAAB
cmpl $0x2, %r13d
jl 0x5e47
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq 0x28(%rsp), %rcx
shll %cl, %edx
movl $0x1, %eax
shll %cl, %eax
notl %edx
movq %rdx, 0xa0(%rsp)
cltq
decq %rax
movq %rax, 0x98(%rsp)
decl %r13d
decl %r13d
movq (%rsp), %rax
leaq (,%r13,2), %rcx
addq %r13, %rcx
movq 0x20(%rax,%rcx,8), %r14
cmpq $-0x1, %r14
je 0x609a
movl %r13d, %edx
leaq (%rdx,%rdx,2), %r15
cmpb $0x1, 0x10(%rax,%r15,8)
jne 0x5d8a
movq 0x220(%rbx), %rdi
movq %r14, %rsi
callq 0x40b0
movq %rax, %rbp
movq 0x18(%rsp), %rdi
movl $0x3, %esi
movl $0x2, %edx
movl $0x1, %ecx
callq 0xcab0
movslq %eax, %r12
leaq (%r12,%rbp), %rax
cmpq $0x1, %rax
jg 0x5d7a
movq 0x18(%rsp), %rdi
movl $0x3, %esi
movl $0x2, %edx
movl $0x1, %ecx
callq 0xcab0
testl %eax, %eax
jne 0x60f7
addq %r12, %rbp
decq %rbp
movq 0x28(%rsp), %rcx
shlq %cl, %rbp
jmp 0x5e08
leaq (%rax,%rcx,8), %rax
cmpb $0x1, 0x28(%rax)
jne 0x5df6
movq 0x220(%rbx), %rdi
movq %r14, %rsi
callq 0x40b0
movq %rax, %rbp
leaq -0x1(%rax), %r12
movq 0x98(%rsp), %rax
cmpq %r12, %rax
cmovlq %rax, %r12
movq 0x18(%rsp), %rdi
movl $0x3, %esi
movl $0x2, %edx
movl $0x1, %ecx
callq 0xcab0
cltq
movq %r12, %rcx
notq %rcx
addq %rax, %rbp
addq %rcx, %rbp
testq %rbp, %rbp
jle 0x60d8
movq 0x28(%rsp), %rcx
shlq %cl, %rbp
addq %r12, %rbp
jmp 0x5e08
testl %r14d, 0xa0(%rsp)
je 0x60b9
leaq -0x1(%r14), %rbp
movq 0x220(%rbx), %rdi
movq %rbp, %rsi
callq 0x40b0
movq %rax, %r12
movq 0x220(%rbx), %rdi
movq %r14, %rsi
callq 0x40b0
decq %rax
cmpq %rax, %r12
jne 0x607b
movq (%rsp), %rax
movq %rbp, 0x8(%rax,%r15,8)
testl %r13d, %r13d
jg 0x5cf1
cmpq $-0x1, 0x1a8(%rbx)
movq 0x90(%rsp), %r15
movq 0x88(%rsp), %r12
movq 0x80(%rsp), %r13
jne 0x5ea0
movq (%rsp), %rax
movq 0x8(%rax), %rsi
movq 0x220(%rbx), %rdi
callq 0x40b0
movl 0x1d4(%rbx), %ecx
movl 0x1d8(%rbx), %edx
imulq %rdx, %rax
imulq $0x3e8, %rax, %rax      # imm = 0x3E8
cqto
idivq %rcx
movq %rax, 0x1a8(%rbx)
cmpq $0x0, 0x1a8(%rbx)
js 0x61b1
movq 0x8(%rsp), %rax
movq -0x10(%rax), %rsi
movq 0x220(%rbx), %rdi
callq 0x40b0
imulq $0x3e8, %rax, %rcx      # imm = 0x3E8
movl $0x3e8, %eax            # imm = 0x3E8
addq %rax, %rcx
movl 0x1d4(%rbx), %esi
movl 0x1d8(%rbx), %eax
imulq %rcx, %rax
cqto
idivq %rsi
movq %rax, 0x1b0(%rbx)
cmpq 0x1a8(%rbx), %rax
jl 0x61d0
movq (%rsp), %rax
cmpq %rax, 0x8(%rsp)
je 0x5f44
movl $0x1, %ebp
xorl %ecx, %ecx
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,8), %rsi
movq %rbx, %rdi
callq 0x6608
movl %ebp, %ecx
movq (%rsp), %rax
movq 0x8(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %rsi # imm = 0xAAAAAAAAAAAAAAAB
imulq %rsi, %rdx
incl %ebp
cmpq %rcx, %rdx
ja 0x5f0d
movq (%rsp), %rax
cmpq %rax, 0x8(%rsp)
leaq 0x38(%rsp), %rbp
je 0x5994
movl $0x1, %ebp
xorl %ecx, %ecx
leaq (%rcx,%rcx,2), %rcx
cmpb $0x1, 0x10(%rax,%rcx,8)
jne 0x5fa3
leaq (%rax,%rcx,8), %rdx
movq 0x268(%rbx), %rsi
cmpq 0x270(%rbx), %rsi
je 0x5f96
movq 0x10(%rdx), %rax
movq %rax, 0x10(%rsi)
movups (%rdx), %xmm0
movups %xmm0, (%rsi)
addq $0x18, 0x268(%rbx)
jmp 0x5fa3
movq 0xb0(%rsp), %rdi
callq 0x6a96
movl %ebp, %ecx
movq (%rsp), %rax
movq 0x8(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %rsi # imm = 0xAAAAAAAAAAAAAAAB
imulq %rsi, %rdx
incl %ebp
cmpq %rcx, %rdx
ja 0x5f5f
jmp 0x598f
movq %r15, %rdi
callq 0x4710
cmpl %eax, 0x20(%rsp)
je 0x6051
movq 0x1100c(%rip), %rdi     # 0x16ff0
leaq 0xa564(%rip), %rsi      # 0x1054f
movl $0x2f, %edx
callq 0x4410
movq 0x250(%rbx), %rsi
subq 0x248(%rbx), %rsi
sarq $0x4, %rsi
movq 0x10fe2(%rip), %rdi     # 0x16ff0
callq 0x4240
movq %rax, %rbx
leaq 0xa562(%rip), %rsi      # 0x1057f
movl $0xf, %edx
movq %rax, %rdi
callq 0x4410
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4360
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x4250
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x6067
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x43a0
movb $0x1, %al
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xa454(%rip), %rdi      # 0x104d6
leaq 0x9f84(%rip), %rsi      # 0x1000d
leaq 0xa2c3(%rip), %rcx      # 0x10353
movl $0x14a, %edx            # imm = 0x14A
callq 0x4210
leaq 0xa3be(%rip), %rdi      # 0x1045f
leaq 0x9f65(%rip), %rsi      # 0x1000d
leaq 0xa2a4(%rip), %rcx      # 0x10353
movl $0x126, %edx            # imm = 0x126
callq 0x4210
leaq 0xa3eb(%rip), %rdi      # 0x104ab
leaq 0x9f46(%rip), %rsi      # 0x1000d
leaq 0xa285(%rip), %rcx      # 0x10353
movl $0x144, %edx            # imm = 0x144
callq 0x4210
leaq 0xa3c0(%rip), %rdi      # 0x1049f
leaq 0x9f27(%rip), %rsi      # 0x1000d
leaq 0xa266(%rip), %rcx      # 0x10353
movl $0x140, %edx            # imm = 0x140
callq 0x4210
leaq 0xa377(%rip), %rdi      # 0x10475
leaq 0x9f08(%rip), %rsi      # 0x1000d
leaq 0xa247(%rip), %rcx      # 0x10353
movl $0x12f, %edx            # imm = 0x12F
callq 0x4210
leaq 0xa205(%rip), %rdi      # 0x10322
leaq 0x9ee9(%rip), %rsi      # 0x1000d
leaq 0xa228(%rip), %rcx      # 0x10353
movl $0xdb, %edx
callq 0x4210
leaq 0x9ec8(%rip), %rdi      # 0x10004
leaq 0x9eca(%rip), %rsi      # 0x1000d
leaq 0xa209(%rip), %rcx      # 0x10353
movl $0xe5, %edx
callq 0x4210
leaq 0xa268(%rip), %rdi      # 0x103c3
leaq 0x9eab(%rip), %rsi      # 0x1000d
leaq 0xa1ea(%rip), %rcx      # 0x10353
movl $0xf7, %edx
callq 0x4210
leaq 0xa274(%rip), %rdi      # 0x103ee
leaq 0x9e8c(%rip), %rsi      # 0x1000d
leaq 0xa1cb(%rip), %rcx      # 0x10353
movl $0x114, %edx            # imm = 0x114
callq 0x4210
leaq 0xa286(%rip), %rdi      # 0x1041f
leaq 0x9e6d(%rip), %rsi      # 0x1000d
leaq 0xa1ac(%rip), %rcx      # 0x10353
movl $0x115, %edx            # imm = 0x115
callq 0x4210
leaq 0xa370(%rip), %rdi      # 0x10528
leaq 0x9e4e(%rip), %rsi      # 0x1000d
leaq 0xa18d(%rip), %rcx      # 0x10353
movl $0x151, %edx            # imm = 0x151
callq 0x4210
leaq 0xa361(%rip), %rdi      # 0x10538
leaq 0x9e2f(%rip), %rsi      # 0x1000d
leaq 0xa16e(%rip), %rcx      # 0x10353
movl $0x153, %edx            # imm = 0x153
callq 0x4210
leaq 0xa1d5(%rip), %rdi      # 0x103cb
leaq 0x9e10(%rip), %rsi      # 0x1000d
leaq 0xa14f(%rip), %rcx      # 0x10353
movl $0xff, %edx
callq 0x4210
jmp 0x6222
jmp 0x6222
jmp 0x6222
jmp 0x6222
jmp 0x6222
jmp 0x6222
jmp 0x6222
jmp 0x6222
jmp 0x6222
jmp 0x6222
movq %rax, %rbx
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x623b
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x43a0
movq %rbx, %rdi
callq 0x46e0
nop