// File: cpearce[P]OggIndex/src/SkeletonEncoder.cpp
// Function: SkeletonEncoder::AddFisbonePackets()
void
SkeletonEncoder::AddFisbonePackets() {
  if (HasFisbonePackets()) {
    // We have fisbone packets from the existing skeleton track. Convert to
    // Skeleton 4.0.
    for (ogg_uint32_t i=1; i<mSkeletonDecoder->mPackets.size()-1; i++) {
      ogg_packet* fisbone = UpdateFisbone(mSkeletonDecoder->mPackets[i]);
      if (fisbone) {
        mIndexPackets.push_back(fisbone);
      }
      mPacketCount++;
    }
  } else {
    // Have to construct fisbone packets.
    for (ogg_uint32_t i=0; i<mDecoders.size(); i++) {
      FisboneInfo info = mDecoders[i]->GetFisboneInfo();
      string headers = info.MessageHeaders();
      unsigned packetSize = FISBONE_HEADER_OFFSET + headers.size();

      ogg_packet* packet = new ogg_packet();
      memset(packet, 0, sizeof(ogg_packet));
      
      packet->packet = new unsigned char[packetSize];
      memset(packet->packet, 0, packetSize);

      // Magic bytes identifier.
      memcpy(packet->packet, FISBONE_MAGIC, FISBONE_MAGIC_LEN);
      
      // Offset of the message header fields.
      WriteLEInt32(packet->packet+FISBONE_HEADERS_OFFSET_FIELD_OFFSET,
                   FISBONE_HEADER_OFFSET);
      
      // Serialno of the stream.
      WriteLEUint32(packet->packet+FISBONE_SERIALNO_OFFSET,
                    mDecoders[i]->GetSerial());

      // Number of header packets. 3 for both vorbis and theora.
      WriteLEUint32(packet->packet+FISBONE_NUM_HEADERS_OFFSET, 3);
      
      // Granulrate numerator.
      WriteLEInt64(packet->packet+FISBONE_GRAN_NUMER_OFFSET, info.mGranNumer);
      
      // Granulrate denominator.
      WriteLEInt64(packet->packet+FISBONE_GRAN_DENOM_OFFSET, info.mGranDenom);
      
      // Start granule.
      WriteLEInt64(packet->packet+FISBONE_START_GRAN_OFFSET, 0);
      
      // Preroll.
      WriteLEUint32(packet->packet+FISBONE_PREROLL_OFFSET, info.mPreroll);
      
      // Granule shift.
      WriteLEUint32(packet->packet+FISBONE_GRAN_SHIFT_OFFSET, info.mGranuleShift);

      // Message header field, Content-Type */
      memcpy(packet->packet+FISBONE_HEADER_OFFSET,
             headers.c_str(),
             headers.size());

      packet->b_o_s = 0;
      packet->e_o_s = 0;
      packet->bytes = packetSize;

      packet->packetno = mPacketCount;      
      mIndexPackets.push_back(packet);
      mPacketCount++;
    }        
  }
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x130(%rsp)
movq 0x130(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x13380
testb $0x1, %al
jne 0x118ea
jmp 0x119a4
movl $0x1, 0x12c(%rsp)
movq 0x58(%rsp), %rax
movl 0x12c(%rsp), %ecx
movq %rcx, 0x50(%rsp)
movq 0x18(%rax), %rdi
addq $0x1d0, %rdi            # imm = 0x1D0
callq 0x6980
movq %rax, %rcx
movq 0x50(%rsp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x1199f
movq 0x58(%rsp), %rax
movq 0x18(%rax), %rdi
addq $0x1d0, %rdi            # imm = 0x1D0
movl 0x12c(%rsp), %eax
movl %eax, %esi
callq 0x69a0
movq 0x58(%rsp), %rdi
movq (%rax), %rsi
callq 0x13490
movq %rax, 0x120(%rsp)
cmpq $0x0, 0x120(%rsp)
je 0x1197b
movq 0x58(%rsp), %rdi
addq $0x38, %rdi
leaq 0x120(%rsp), %rsi
callq 0x14030
movq 0x58(%rsp), %rax
movl 0x34(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x34(%rax)
movl 0x12c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x12c(%rsp)
jmp 0x118f5
jmp 0x11c99
movl $0x0, 0x11c(%rsp)
movq 0x58(%rsp), %rdi
movl 0x11c(%rsp), %eax
movq %rax, 0x48(%rsp)
callq 0x140a0
movq %rax, %rcx
movq 0x48(%rsp), %rax
cmpq %rcx, %rax
jae 0x11c97
movq 0x58(%rsp), %rdi
movl 0x11c(%rsp), %eax
movl %eax, %esi
callq 0x140c0
movq (%rax), %rsi
movq (%rsi), %rax
movq 0x40(%rax), %rax
leaq 0x98(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq *%rax
movq 0x40(%rsp), %rsi
leaq 0x78(%rsp), %rdi
callq 0x14550
jmp 0x11a13
leaq 0x78(%rsp), %rdi
callq 0x52d0
addl $0x34, %eax
movl %eax, 0x68(%rsp)
movl $0x30, %edi
callq 0x53e0
movq %rax, 0x38(%rsp)
jmp 0x11a35
movq 0x38(%rsp), %rax
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rax)
movaps %xmm0, 0x10(%rax)
movaps %xmm0, (%rax)
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movups %xmm0, 0x20(%rax)
movups %xmm0, 0x10(%rax)
movups %xmm0, (%rax)
movl 0x68(%rsp), %eax
movl %eax, %edi
callq 0x5030
movq %rax, 0x30(%rsp)
jmp 0x11a6f
movq 0x30(%rsp), %rcx
movq 0x60(%rsp), %rax
movq %rcx, (%rax)
movq 0x60(%rsp), %rax
movq (%rax), %rdi
movl 0x68(%rsp), %eax
movl %eax, %edx
xorl %esi, %esi
callq 0x5230
movq 0x60(%rsp), %rax
movq (%rax), %rax
movabsq $0x656e6f62736966, %rcx # imm = 0x656E6F62736966
movq %rcx, (%rax)
movq 0x60(%rsp), %rax
movq (%rax), %rdi
addq $0x8, %rdi
movl $0x34, %esi
callq 0x16dd0
jmp 0x11abe
movq 0x58(%rsp), %rdi
movq 0x60(%rsp), %rax
movq (%rax), %rax
addq $0xc, %rax
movq %rax, 0x20(%rsp)
movl 0x11c(%rsp), %eax
movl %eax, %esi
callq 0x140c0
movq (%rax), %rdi
callq 0x13f80
movl %eax, 0x2c(%rsp)
jmp 0x11af0
movl 0x2c(%rsp), %esi
movq 0x20(%rsp), %rdi
callq 0x16d10
jmp 0x11b00
movq 0x60(%rsp), %rax
movq (%rax), %rdi
addq $0x10, %rdi
movl $0x3, %esi
callq 0x16d10
jmp 0x11b18
movq 0x60(%rsp), %rax
movq (%rax), %rdi
addq $0x14, %rdi
movq 0x98(%rsp), %rsi
callq 0x16bf0
jmp 0x11b33
movq 0x60(%rsp), %rax
movq (%rax), %rdi
addq $0x1c, %rdi
movq 0xa0(%rsp), %rsi
callq 0x16bf0
jmp 0x11b4e
movq 0x60(%rsp), %rax
movq (%rax), %rdi
addq $0x24, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x16bf0
jmp 0x11b65
movq 0x60(%rsp), %rax
movq (%rax), %rdi
addq $0x2c, %rdi
movl 0xa8(%rsp), %esi
callq 0x16d10
jmp 0x11b7f
movq 0x60(%rsp), %rax
movq (%rax), %rdi
addq $0x30, %rdi
movl 0xac(%rsp), %esi
callq 0x16d10
jmp 0x11b99
movq 0x60(%rsp), %rax
movq (%rax), %rax
addq $0x34, %rax
movq %rax, 0x10(%rsp)
leaq 0x78(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x5180
movq 0x8(%rsp), %rdi
movq %rax, 0x18(%rsp)
callq 0x52d0
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq %rax, %rdx
callq 0x5340
movq 0x58(%rsp), %rdi
movq 0x60(%rsp), %rax
movq $0x0, 0x10(%rax)
movq 0x60(%rsp), %rax
movq $0x0, 0x18(%rax)
movl 0x68(%rsp), %eax
movl %eax, %ecx
movq 0x60(%rsp), %rax
movq %rcx, 0x8(%rax)
movslq 0x34(%rdi), %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x28(%rax)
addq $0x38, %rdi
leaq 0x60(%rsp), %rsi
callq 0x14030
jmp 0x11c25
movq 0x58(%rsp), %rax
movl 0x34(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x34(%rax)
leaq 0x78(%rsp), %rdi
callq 0x5260
leaq 0x98(%rsp), %rdi
callq 0xaf10
movl 0x11c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x11c(%rsp)
jmp 0x119af
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x70(%rsp)
movl %eax, 0x6c(%rsp)
jmp 0x11c88
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x70(%rsp)
movl %eax, 0x6c(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x5260
leaq 0x98(%rsp), %rdi
callq 0xaf10
jmp 0x11ca1
jmp 0x11c99
addq $0x138, %rsp            # imm = 0x138
retq
movq 0x70(%rsp), %rdi
callq 0x57d0
nopl (%rax,%rax)