// File: /workspace/github_cpp_makefile_star2_O2/cpearce[P]OggIndex/src/Decoder.cpp
// Function: VorbisDecoder::Decode(ogg_page*, long)
bool Decode(ogg_page* page, ogg_int64_t offset) {
    if (GotAllHeaders()) {
      // Reset the vorbis syntheis. This simulates what happens when we seek
      // to this page and start decoding with no prior knowledge. This forces
      // the decoder to preroll again.
      ogg_stream_reset(&mState);
      vorbis_synthesis_restart(&mDsp);
    }

    ogg_packet packet;
    assert(ogg_stream_packetout(&mState, &packet) == 0);
    int ret = ogg_stream_pagein(&mState, page);
    assert(ret == 0);
    int total_samples = 0;
    ogg_int64_t start_time = -1;

    while ((ret = ogg_stream_packetout(&mState, &packet)) == 1) {

      if (!GotAllHeaders()) {
        ogg_int32_t ret = vorbis_synthesis_headerin(&mInfo, &mComment, &packet);
        if (ret == 0) {
          mHeadersRead++;
        }
        if (gOptions.GetDumpPackets()) {
          cout << "[V] ver="
               << (int)mInfo.version << " "
               << VorbisHeaderType(&packet) << " packet"
               << (packet.e_o_s ? " eos" : "")
               << endl;
        }
        if (GotAllHeaders()) {
          ret = vorbis_synthesis_init(&mDsp, &mInfo);
          assert(ret == 0);
          ret = vorbis_block_init(&mDsp, &mBlock);
          assert(ret == 0);
        }
        continue;
      }
      assert(GotAllHeaders());

      // Decode page, get start and end time.
      // We only expect the last packet in a page to have non -1 granulepos.
      assert(start_time == -1);
      int samples = 0;
      
      // Decode the vorbis to determine how many samples are in each packet.
      if (vorbis_synthesis(&mBlock, &packet) == 0) {
        ret = vorbis_synthesis_blockin(&mDsp, &mBlock);
        assert(ret == 0);
      }
      while ((samples = vorbis_synthesis_pcmout(&mDsp, 0)) > 0) {
        total_samples += samples;
        ret = vorbis_synthesis_read(&mDsp, samples);
        assert(ret == 0);
      }

      if (packet.granulepos != -1) {
        assert(packet.granulepos == ogg_page_granulepos(page));
        ogg_int64_t start_granule = packet.granulepos - total_samples;
        start_time = Time(start_granule);
        if (!mGotFirstContentPage && start_time < 0) {
          // The first content page may specify fewer samples in its granulepos
          // than are actually in the the first page. As per the vorbis spec,
          // these should not be played, so we exclude them here.
          start_time = 0;
        }
        ogg_int64_t end_time = Time(packet.granulepos);

        mGotFirstContentPage = true;


        // First packet will be included in the index, the cut off threshold
        // is then set relative to that.

        if (gOptions.GetDumpKeyPackets() || gOptions.GetDumpPackets()) {
          cout << "[V] sample time_ms=[" << start_time << "," << end_time
               << "] granulepos=[" << start_granule << ","
               << packet.granulepos << "]"
               << (packet.e_o_s ? " eos" : "")
               << endl;
        }    

        assert(start_time >= 0);
        if (start_time > mNextKeyframeThreshold) {
          mKeyFrames.push_back(KeyFrameInfo(offset, start_time));
          mNextKeyframeThreshold = Time(ogg_page_granulepos(page)) +
                                   gOptions.GetKeyPointInterval();
        }
        assert(ogg_stream_packetout(&mState, &packet) == 0);
        
        if (mStartTime == -1) {
          mStartTime = start_time;
        }
        mEndTime = end_time;

      }
    } // while packetout

    return true;
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rdx, 0x38(%rsp)
movq %rsi, %rbx
movq %rdi, %r15
movq (%rdi), %rax
callq *0x18(%rax)
testb %al, %al
je 0x67df
leaq 0x8(%r15), %rdi
callq 0x4360
leaq 0x238(%r15), %rdi
callq 0x44f0
leaq 0x8(%r15), %r12
leaq 0x58(%rsp), %rsi
movq %r12, %rdi
callq 0x4550
testl %eax, %eax
jne 0x6c31
movq %r12, %rdi
movq %rbx, 0x20(%rsp)
movq %rbx, %rsi
callq 0x4500
testl %eax, %eax
jne 0x6c50
leaq 0x1e0(%r15), %r13
leaq 0x218(%r15), %rax
movq %rax, 0x40(%rsp)
leaq 0x238(%r15), %rbx
leaq 0x2c8(%r15), %rax
movq %rax, 0x10(%rsp)
leaq 0x1c0(%r15), %rax
movq %rax, 0x30(%rsp)
xorl %ebp, %ebp
pushq $-0x1
popq %rax
leaq 0x58(%rsp), %r14
movq %rax, 0x8(%rsp)
movq %r12, %rdi
movq %r14, %rsi
callq 0x4550
cmpl $0x1, %eax
jne 0x6bc0
movq (%r15), %rax
movq %r15, %rdi
callq *0x18(%rax)
testb %al, %al
jne 0x6976
movq %r13, %rdi
movq 0x40(%rsp), %rsi
movq %r14, %rdx
callq 0x4110
testl %eax, %eax
jne 0x6891
incl 0x1dc(%r15)
leaq 0xeb68(%rip), %rdi      # 0x15400
callq 0x82d6
testb %al, %al
je 0x6938
movq 0xe724(%rip), %rdi      # 0x14fd0
leaq 0x7ea6(%rip), %rsi      # 0xe759
callq 0x4340
movl (%r13), %esi
movq %rax, %rdi
callq 0x4650
movq %rax, %rdi
leaq 0x8cf4(%rip), %rsi      # 0xf5c2
callq 0x4340
movq 0x58(%rsp), %rcx
movb (%rcx), %cl
decb %cl
leaq 0x7cda(%rip), %rsi      # 0xe5bd
cmpb $0x4, %cl
ja 0x68f9
movzbl %cl, %ecx
leaq 0x7f7e(%rip), %rdx      # 0xe870
movslq (%rdx,%rcx,4), %rsi
addq %rdx, %rsi
movq %rax, %rdi
callq 0x4340
movq %rax, %rdi
leaq 0x7ad6(%rip), %rsi      # 0xe3e1
callq 0x4340
cmpq $0x0, 0x70(%rsp)
leaq 0x7acc(%rip), %rsi      # 0xe3e9
leaq 0x8ac6(%rip), %rcx      # 0xf3ea
cmoveq %rcx, %rsi
movq %rax, %rdi
callq 0x4340
movq %rax, %rdi
callq 0x41b0
movq (%r15), %rax
movq %r15, %rdi
callq *0x18(%rax)
testb %al, %al
je 0x6851
movq %rbx, %rdi
movq %r13, %rsi
callq 0x42f0
testl %eax, %eax
jne 0x6c12
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
callq 0x4490
testl %eax, %eax
je 0x6851
jmp 0x6bf3
movq (%r15), %rax
movq %r15, %rdi
callq *0x18(%rax)
testb %al, %al
je 0x6c6f
cmpq $-0x1, 0x8(%rsp)
movq 0x10(%rsp), %rdi
jne 0x6c8e
movq %r14, %rsi
callq 0x41e0
testl %eax, %eax
jne 0x69b9
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
callq 0x42a0
testl %eax, %eax
jne 0x6d0a
movq %rbx, %rdi
xorl %esi, %esi
callq 0x43d0
testl %eax, %eax
jle 0x69dc
addl %eax, %ebp
movq %rbx, %rdi
movl %eax, %esi
callq 0x4510
testl %eax, %eax
je 0x69b9
jmp 0x6bd4
movq 0x78(%rsp), %rcx
pushq $-0x1
popq %rax
cmpq $-0x1, %rcx
je 0x684c
movq 0x20(%rsp), %rdi
movq %rcx, 0x8(%rsp)
callq 0x45c0
cmpq %rax, 0x8(%rsp)
jne 0x6cad
movq 0x78(%rsp), %rsi
movl %ebp, %eax
subq %rax, %rsi
movq %r15, %rdi
movq %rsi, 0x28(%rsp)
callq 0x6df8
cmpb $0x0, 0x1d8(%r15)
movl $0x0, %ecx
cmovneq %rax, %rcx
testq %rax, %rax
cmovnsq %rax, %rcx
movq %rcx, 0x8(%rsp)
movq 0x78(%rsp), %rsi
movq %r15, %rdi
callq 0x6df8
movq %rax, 0x18(%rsp)
movb $0x1, 0x1d8(%r15)
leaq 0xe9a3(%rip), %rax      # 0x15400
cmpb $0x0, 0x1(%rax)
jne 0x6a77
leaq 0xe996(%rip), %rdi      # 0x15400
callq 0x82d6
testb %al, %al
je 0x6b22
movq 0xe552(%rip), %rdi      # 0x14fd0
leaq 0x7d2d(%rip), %rsi      # 0xe7b2
callq 0x4340
movq %rax, %rdi
movq 0x8(%rsp), %rsi
callq 0x4320
movq %rax, %rdi
leaq 0x863d(%rip), %rsi      # 0xf0de
callq 0x4340
movq %rax, %rdi
movq 0x18(%rsp), %rsi
callq 0x4320
movq %rax, %rdi
leaq 0x7d0a(%rip), %rsi      # 0xe7c7
callq 0x4340
movq %rax, %rdi
movq 0x28(%rsp), %rsi
callq 0x4320
movq %rax, %rdi
leaq 0x8605(%rip), %rsi      # 0xf0de
callq 0x4340
movq 0x78(%rsp), %rsi
movq %rax, %rdi
callq 0x4320
movq %rax, %rdi
leaq 0x7696(%rip), %rsi      # 0xe18b
callq 0x4340
cmpq $0x0, 0x70(%rsp)
leaq 0x78e2(%rip), %rsi      # 0xe3e9
leaq 0x88dc(%rip), %rcx      # 0xf3ea
cmoveq %rcx, %rsi
movq %rax, %rdi
callq 0x4340
movq %rax, %rdi
callq 0x41b0
movq 0x8(%rsp), %rax
testq %rax, %rax
js 0x6ceb
cmpq 0x1b8(%r15), %rax
jle 0x6b86
movq 0x38(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x8(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x30(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x6e9a
movq 0x20(%rsp), %rdi
callq 0x45c0
movq %r15, %rdi
movq %rax, %rsi
callq 0x6df8
leaq 0xe888(%rip), %rcx      # 0x15400
movslq 0x48(%rcx), %rcx
addq %rax, %rcx
movq %rcx, 0x1b8(%r15)
movq %r12, %rdi
movq %r14, %rsi
callq 0x4550
testl %eax, %eax
jne 0x6ccc
cmpq $-0x1, 0x1a8(%r15)
movq 0x8(%rsp), %rax
jne 0x6baf
movq %rax, 0x1a8(%r15)
movq 0x18(%rsp), %rcx
movq %rcx, 0x1b0(%r15)
jmp 0x684c
movb $0x1, %al
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x7429(%rip), %rdi      # 0xe004
leaq 0x742b(%rip), %rsi      # 0xe00d
leaq 0x7b34(%rip), %rcx      # 0xe71d
movl $0x1e9, %edx            # imm = 0x1E9
callq 0x4210
leaq 0x740a(%rip), %rdi      # 0xe004
leaq 0x740c(%rip), %rsi      # 0xe00d
leaq 0x7b15(%rip), %rcx      # 0xe71d
movl $0x1d6, %edx            # imm = 0x1D6
callq 0x4210
leaq 0x73eb(%rip), %rdi      # 0xe004
leaq 0x73ed(%rip), %rsi      # 0xe00d
leaq 0x7af6(%rip), %rcx      # 0xe71d
movl $0x1d4, %edx            # imm = 0x1D4
callq 0x4210
leaq 0x7ab9(%rip), %rdi      # 0xe6f1
leaq 0x73ce(%rip), %rsi      # 0xe00d
leaq 0x7ad7(%rip), %rcx      # 0xe71d
movl $0x1be, %edx            # imm = 0x1BE
callq 0x4210
leaq 0x73ad(%rip), %rdi      # 0xe004
leaq 0x73af(%rip), %rsi      # 0xe00d
leaq 0x7ab8(%rip), %rcx      # 0xe71d
movl $0x1c0, %edx            # imm = 0x1C0
callq 0x4210
leaq 0x7aec(%rip), %rdi      # 0xe762
leaq 0x7390(%rip), %rsi      # 0xe00d
leaq 0x7a99(%rip), %rcx      # 0xe71d
movl $0x1da, %edx            # imm = 0x1DA
callq 0x4210
leaq 0x7add(%rip), %rdi      # 0xe772
leaq 0x7371(%rip), %rsi      # 0xe00d
leaq 0x7a7a(%rip), %rcx      # 0xe71d
movl $0x1de, %edx            # imm = 0x1DE
callq 0x4210
leaq 0x7acf(%rip), %rdi      # 0xe783
leaq 0x7352(%rip), %rsi      # 0xe00d
leaq 0x7a5b(%rip), %rcx      # 0xe71d
movl $0x1ed, %edx            # imm = 0x1ED
callq 0x4210
leaq 0x7a1e(%rip), %rdi      # 0xe6f1
leaq 0x7333(%rip), %rsi      # 0xe00d
leaq 0x7a3c(%rip), %rcx      # 0xe71d
movl $0x20c, %edx            # imm = 0x20C
callq 0x4210
leaq 0x7ae4(%rip), %rdi      # 0xe7d6
leaq 0x7314(%rip), %rsi      # 0xe00d
leaq 0x7a1d(%rip), %rcx      # 0xe71d
movl $0x206, %edx            # imm = 0x206
callq 0x4210
leaq 0x72f3(%rip), %rdi      # 0xe004
leaq 0x72f5(%rip), %rsi      # 0xe00d
leaq 0x79fe(%rip), %rcx      # 0xe71d
movl $0x1e4, %edx            # imm = 0x1E4
callq 0x4210
nop