// File: /workspace/github_cpp_makefile_star2_O3/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 $0xc8, %rsp
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x42d0
cmpl 0x1a0(%rbx), %eax
jne 0x60a4
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x18(%rax)
testb %al, %al
je 0x589f
movq %r15, %rdi
callq 0xc84d
movl %eax, 0x70(%rsp)
movq %r14, 0x68(%rsp)
movq 0x250(%rbx), %rsi
cmpq 0x258(%rbx), %rsi
je 0x588e
movups 0x68(%rsp), %xmm0
movups %xmm0, (%rsi)
addq $0x10, 0x250(%rbx)
jmp 0x589f
leaq 0x248(%rbx), %rdi
leaq 0x68(%rsp), %rdx
callq 0x6700
leaq 0x8(%rbx), %r13
movq %r13, %rdi
movq %r15, %rsi
callq 0x4540
movl %eax, %ebp
movq %r15, %rdi
callq 0x4610
testl %ebp, %ebp
jne 0x60c3
movq %rax, %r12
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rax
movaps %xmm0, (%rax)
movq $0x0, 0x10(%rax)
leaq 0x1b8(%rbx), %rax
movq %rax, 0x8(%rsp)
leaq 0x1f8(%rbx), %rax
movq %rax, 0xb8(%rsp)
leaq 0x218(%rbx), %rax
movq %rax, 0x40(%rsp)
leaq 0x260(%rbx), %rax
movq %rax, 0xc0(%rsp)
movq $0x0, 0x30(%rsp)
movq %r12, 0x48(%rsp)
movq %r13, %rdi
leaq 0x68(%rsp), %rsi
callq 0x4590
cmpl $-0x1, %eax
jne 0x598e
movl $0x33, %edx
movq 0x116b8(%rip), %rdi     # 0x16ff0
leaq 0xaa50(%rip), %rsi      # 0x1038f
callq 0x4410
movq 0x250(%rbx), %rsi
subq 0x248(%rbx), %rsi
sarq $0x4, %rsi
movq 0x11693(%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 0x591a
testl %eax, %eax
je 0x5f5c
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x18(%rax)
movq 0x30(%rsp), %rcx
incl %ecx
movq %rcx, 0x30(%rsp)
testb %al, %al
je 0x5a67
cmpq $-0x1, 0x240(%rbx)
jne 0x59cc
movq 0x90(%rsp), %rax
movq %rax, 0x240(%rbx)
cmpq $-0x1, %r12
setne %cl
movq 0x88(%rsp), %rax
cmpq $-0x1, %rax
sete %dl
orb %cl, %dl
je 0x6101
cmpq $-0x1, %rax
sete %cl
cmpq %r12, %rax
sete %dl
orb %cl, %dl
je 0x6120
movl 0x1f4(%rbx), %ecx
movq %rcx, 0x38(%rsp)
movq 0x90(%rsp), %rcx
movq %rcx, 0x50(%rsp)
movq %rax, 0x58(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x42a0
testl %eax, %eax
setne 0x60(%rsp)
cmpq $0x0, 0x80(%rsp)
setne 0x61(%rsp)
movq 0x18(%rsp), %rsi
cmpq 0x20(%rsp), %rsi
je 0x5c10
movq 0x60(%rsp), %rax
movq %rax, 0x10(%rsi)
movups 0x50(%rsp), %xmm0
movups %xmm0, (%rsi)
addq $0x18, 0x18(%rsp)
jmp 0x5c1f
movq 0x8(%rsp), %rdi
movq 0xb8(%rsp), %rsi
movq 0x40(%rsp), %rdx
leaq 0x68(%rsp), %rcx
callq 0x45f0
testl %eax, %eax
jle 0x60e2
incl 0x228(%rbx)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x18(%rax)
testb %al, %al
je 0x5ac0
movq 0x40(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rsp), %rdi
callq 0x4440
movq %rax, 0x220(%rbx)
testq %rax, %rax
je 0x617d
leaq 0x11949(%rip), %rdi     # 0x17410
callq 0x8b3a
testb %al, %al
je 0x591a
movl $0x8, %edx
movq 0x114f0(%rip), %rdi     # 0x16fd0
leaq 0xa8f1(%rip), %rsi      # 0x103d8
callq 0x4410
movq 0x8(%rsp), %rax
movzbl (%rax), %esi
movq 0x114d5(%rip), %rdi     # 0x16fd0
callq 0x4690
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0xb05b(%rip), %rsi      # 0x10b6d
callq 0x4410
movzbl 0x1b9(%rbx), %esi
movq %r14, %rdi
callq 0x4690
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0xb035(%rip), %rsi      # 0x10b6d
callq 0x4410
movzbl 0x1ba(%rbx), %esi
movq %r14, %rdi
callq 0x4690
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0xba6a(%rip), %rsi      # 0x115c8
callq 0x4410
movq 0x68(%rsp), %rax
movzbl (%rax), %eax
xorq $0x80, %rax
leaq 0xaa45(%rip), %r12      # 0x105bd
cmpb $0x2, %al
ja 0x5b8a
leaq 0xace1(%rip), %rcx      # 0x10864
movslq (%rcx,%rax,4), %r12
addq %rcx, %r12
movq %r12, %rdi
callq 0x4170
movq %r14, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x4410
movq 0x48(%rsp), %r12
movl $0x7, %edx
movq %r14, %rdi
leaq 0xa82d(%rip), %rsi      # 0x103e1
callq 0x4410
xorl %edx, %edx
cmpq $0x0, 0x80(%rsp)
setne %dl
leaq 0xa81b(%rip), %rsi      # 0x103e9
leaq 0xb845(%rip), %rax      # 0x1141a
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 0x591a
leaq 0x10(%rsp), %rdi
leaq 0x50(%rsp), %rdx
callq 0x6840
cmpq $-0x1, 0x88(%rsp)
je 0x591a
movq %r13, 0xa0(%rsp)
movq %r15, 0x98(%rsp)
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
subq %rax, %rcx
shrq $0x3, %rcx
imull $0xaaaaaaab, %ecx, %r13d # imm = 0xAAAAAAAB
cmpl $0x2, %r13d
jl 0x5ddf
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movq 0x38(%rsp), %rcx
shll %cl, %esi
movl $0x1, %edx
shll %cl, %edx
notl %esi
movq %rsi, 0xb0(%rsp)
movslq %edx, %rcx
decq %rcx
movq %rcx, 0xa8(%rsp)
decl %r13d
decl %r13d
leaq (,%r13,2), %r15
addq %r13, %r15
movq 0x20(%rax,%r15,8), %r14
cmpq $-0x1, %r14
je 0x6028
cmpb $0x1, 0x10(%rax,%r15,8)
jne 0x5d1c
movq 0x220(%rbx), %rdi
movq %r14, %rsi
callq 0x40b0
movq %rax, %r12
movq 0x8(%rsp), %rdi
movl $0x3, %esi
movl $0x2, %edx
movl $0x1, %ecx
callq 0xc826
movslq %eax, %rbp
leaq (%r12,%rbp), %rax
cmpq $0x1, %rax
jg 0x5d0c
movq 0x8(%rsp), %rdi
movl $0x3, %esi
movl $0x2, %edx
movl $0x1, %ecx
callq 0xc826
testl %eax, %eax
jne 0x6085
addq %rbp, %r12
decq %r12
movq 0x38(%rsp), %rcx
shlq %cl, %r12
jmp 0x5d9a
leaq (%rax,%r15,8), %rax
cmpb $0x1, 0x28(%rax)
jne 0x5d88
movq 0x220(%rbx), %rdi
movq %r14, %rsi
callq 0x40b0
movq %rax, %r12
leaq -0x1(%rax), %rbp
movq 0xa8(%rsp), %rax
cmpq %rbp, %rax
cmovlq %rax, %rbp
movq 0x8(%rsp), %rdi
movl $0x3, %esi
movl $0x2, %edx
movl $0x1, %ecx
callq 0xc826
cltq
movq %rbp, %rcx
notq %rcx
addq %rax, %r12
addq %rcx, %r12
testq %r12, %r12
jle 0x6066
movq 0x38(%rsp), %rcx
shlq %cl, %r12
addq %rbp, %r12
jmp 0x5d9a
testl %r14d, 0xb0(%rsp)
je 0x6047
leaq -0x1(%r14), %r12
movq 0x220(%rbx), %rdi
movq %r12, %rsi
callq 0x40b0
movq %rax, %rbp
movq 0x220(%rbx), %rdi
movq %r14, %rsi
callq 0x40b0
decq %rax
cmpq %rax, %rbp
jne 0x6009
movq 0x10(%rsp), %rax
movq %r12, 0x8(%rax,%r15,8)
testl %r13d, %r13d
movq 0x48(%rsp), %r12
jg 0x5c8e
movq 0x1a8(%rbx), %rax
cmpq $-0x1, %rax
movq 0xa0(%rsp), %r13
jne 0x5e2c
movq 0x10(%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)
testq %rax, %rax
js 0x613f
movq 0x18(%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 0x615e
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
cmpq %rax, %rcx
movq 0x98(%rsp), %r15
je 0x5edb
movl $0x1, %ebp
xorl %edx, %edx
leaq (%rdx,%rdx,2), %rcx
leaq (%rax,%rcx,8), %rsi
movq %rbx, %rdi
callq 0x6548
movl %ebp, %edx
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
movq %rcx, %rsi
subq %rax, %rsi
sarq $0x3, %rsi
movabsq $-0x5555555555555555, %rdi # imm = 0xAAAAAAAAAAAAAAAB
imulq %rdi, %rsi
incl %ebp
cmpq %rdx, %rsi
ja 0x5ea0
cmpq %rax, %rcx
je 0x591a
movl $0x1, %ebp
xorl %ecx, %ecx
leaq (%rcx,%rcx,2), %rcx
cmpb $0x1, 0x10(%rax,%rcx,8)
jne 0x5f2f
leaq (%rax,%rcx,8), %rdx
movq 0x268(%rbx), %rsi
cmpq 0x270(%rbx), %rsi
je 0x5f22
movq 0x10(%rdx), %rax
movq %rax, 0x10(%rsi)
movups (%rdx), %xmm0
movups %xmm0, (%rsi)
addq $0x18, 0x268(%rbx)
jmp 0x5f2f
movq 0xc0(%rsp), %rdi
callq 0x69d6
movl %ebp, %ecx
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %rsi # imm = 0xAAAAAAAAAAAAAAAB
imulq %rsi, %rdx
incl %ebp
cmpq %rcx, %rdx
ja 0x5eeb
jmp 0x591a
movq %r15, %rdi
callq 0x4700
cmpl %eax, 0x30(%rsp)
je 0x5fde
movq 0x1107f(%rip), %rdi     # 0x16ff0
leaq 0xa5d7(%rip), %rsi      # 0x1054f
movl $0x2f, %edx
callq 0x4410
movq 0x250(%rbx), %rsi
subq 0x248(%rbx), %rsi
sarq $0x4, %rsi
movq 0x11055(%rip), %rdi     # 0x16ff0
callq 0x4240
movq %rax, %rbx
leaq 0xa5d5(%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 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x5ff5
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x43a0
movb $0x1, %al
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xa4c6(%rip), %rdi      # 0x104d6
leaq 0x9ff6(%rip), %rsi      # 0x1000d
leaq 0xa335(%rip), %rcx      # 0x10353
movl $0x14a, %edx            # imm = 0x14A
callq 0x4210
leaq 0xa430(%rip), %rdi      # 0x1045f
leaq 0x9fd7(%rip), %rsi      # 0x1000d
leaq 0xa316(%rip), %rcx      # 0x10353
movl $0x126, %edx            # imm = 0x126
callq 0x4210
leaq 0xa45d(%rip), %rdi      # 0x104ab
leaq 0x9fb8(%rip), %rsi      # 0x1000d
leaq 0xa2f7(%rip), %rcx      # 0x10353
movl $0x144, %edx            # imm = 0x144
callq 0x4210
leaq 0xa432(%rip), %rdi      # 0x1049f
leaq 0x9f99(%rip), %rsi      # 0x1000d
leaq 0xa2d8(%rip), %rcx      # 0x10353
movl $0x140, %edx            # imm = 0x140
callq 0x4210
leaq 0xa3e9(%rip), %rdi      # 0x10475
leaq 0x9f7a(%rip), %rsi      # 0x1000d
leaq 0xa2b9(%rip), %rcx      # 0x10353
movl $0x12f, %edx            # imm = 0x12F
callq 0x4210
leaq 0xa277(%rip), %rdi      # 0x10322
leaq 0x9f5b(%rip), %rsi      # 0x1000d
leaq 0xa29a(%rip), %rcx      # 0x10353
movl $0xdb, %edx
callq 0x4210
leaq 0x9f3a(%rip), %rdi      # 0x10004
leaq 0x9f3c(%rip), %rsi      # 0x1000d
leaq 0xa27b(%rip), %rcx      # 0x10353
movl $0xe5, %edx
callq 0x4210
leaq 0xa2da(%rip), %rdi      # 0x103c3
leaq 0x9f1d(%rip), %rsi      # 0x1000d
leaq 0xa25c(%rip), %rcx      # 0x10353
movl $0xf7, %edx
callq 0x4210
leaq 0xa2e6(%rip), %rdi      # 0x103ee
leaq 0x9efe(%rip), %rsi      # 0x1000d
leaq 0xa23d(%rip), %rcx      # 0x10353
movl $0x114, %edx            # imm = 0x114
callq 0x4210
leaq 0xa2f8(%rip), %rdi      # 0x1041f
leaq 0x9edf(%rip), %rsi      # 0x1000d
leaq 0xa21e(%rip), %rcx      # 0x10353
movl $0x115, %edx            # imm = 0x115
callq 0x4210
leaq 0xa3e2(%rip), %rdi      # 0x10528
leaq 0x9ec0(%rip), %rsi      # 0x1000d
leaq 0xa1ff(%rip), %rcx      # 0x10353
movl $0x151, %edx            # imm = 0x151
callq 0x4210
leaq 0xa3d3(%rip), %rdi      # 0x10538
leaq 0x9ea1(%rip), %rsi      # 0x1000d
leaq 0xa1e0(%rip), %rcx      # 0x10353
movl $0x153, %edx            # imm = 0x153
callq 0x4210
leaq 0xa247(%rip), %rdi      # 0x103cb
leaq 0x9e82(%rip), %rsi      # 0x1000d
leaq 0xa1c1(%rip), %rcx      # 0x10353
movl $0xff, %edx
callq 0x4210
jmp 0x61b0
jmp 0x61b0
jmp 0x61b0
jmp 0x61b0
jmp 0x61b0
jmp 0x61b0
jmp 0x61b0
jmp 0x61b0
jmp 0x61b0
jmp 0x61b0
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x61ca
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x43a0
movq %rbx, %rdi
callq 0x46d0