コード例 #1
0
uint64 EbmlElementSize(uint64 type, const char* value) {
  if (!value)
    return 0;

  // Size of EBML ID
  uint64 ebml_size = GetUIntSize(type);

  // Datasize
  ebml_size += strlen(value);

  // Size of Datasize
  ebml_size++;

  return ebml_size;
}
コード例 #2
0
uint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size) {
  if (!value)
    return 0;

  // Size of EBML ID
  uint64 ebml_size = GetUIntSize(type);

  // Datasize
  ebml_size += size;

  // Size of Datasize
  ebml_size += GetCodedUIntSize(size);

  return ebml_size;
}
コード例 #3
0
bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value) {
    if (!writer)
        return false;

    if (WriteID(writer, type))
        return false;

    const uint64 size = GetUIntSize(value);
    if (WriteUInt(writer, size))
        return false;

    if (SerializeInt(writer, value, static_cast<int32>(size)))
        return false;

    return true;
}
コード例 #4
0
// We must write the metadata (key)frame as a BlockGroup element,
// because we need to specify a duration for the frame.  The
// BlockGroup element comprises the frame itself and its duration,
// and is laid out as follows:
//
//   BlockGroup tag
//   BlockGroup size
//     Block tag
//     Block size
//     (the frame is the block payload)
//     Duration tag
//     Duration size
//     (duration payload)
//
uint64 WriteMetadataBlock(IMkvWriter* writer,
                          const uint8* data,
                          uint64 length,
                          uint64 track_number,
                          int64 timecode,
                          uint64 duration) {
    // We don't backtrack when writing to the stream, so we must
    // pre-compute the BlockGroup size, by summing the sizes of each
    // sub-element (the block and the duration).

    // We use a single byte for the track number of the block, which
    // means the block header is exactly 4 bytes.

    // TODO(matthewjheaney): use EbmlMasterElementSize and WriteEbmlMasterElement

    const uint64 block_payload_size = 4 + length;
    const int32 block_size = GetCodedUIntSize(block_payload_size);
    const uint64 block_elem_size = 1 + block_size + block_payload_size;

    const int32 duration_payload_size = GetUIntSize(duration);
    const int32 duration_size = GetCodedUIntSize(duration_payload_size);
    const uint64 duration_elem_size = 1 + duration_size + duration_payload_size;

    const uint64 blockg_payload_size = block_elem_size + duration_elem_size;
    const int32 blockg_size = GetCodedUIntSize(blockg_payload_size);
    const uint64 blockg_elem_size = 1 + blockg_size + blockg_payload_size;

    if (WriteID(writer, kMkvBlockGroup))  // 1-byte ID size
        return 0;

    if (WriteUInt(writer, blockg_payload_size))
        return 0;

    //  Write Block element

    if (WriteID(writer, kMkvBlock))  // 1-byte ID size
        return 0;

    if (WriteUInt(writer, block_payload_size))
        return 0;

    // Byte 1 of 4

    if (WriteUInt(writer, track_number))
        return 0;

    // Bytes 2 & 3 of 4

    if (SerializeInt(writer, timecode, 2))
        return 0;

    // Byte 4 of 4

    const uint64 flags = 0;

    if (SerializeInt(writer, flags, 1))
        return 0;

    // Now write the actual frame (of metadata)

    if (writer->Write(data, static_cast<uint32>(length)))
        return 0;

    // Write Duration element

    if (WriteID(writer, kMkvBlockDuration))  // 1-byte ID size
        return 0;

    if (WriteUInt(writer, duration_payload_size))
        return 0;

    if (SerializeInt(writer, duration, duration_payload_size))
        return 0;

    // Note that we don't write a reference time as part of the block
    // group; no reference time(s) indicates that this block is a
    // keyframe.  (Unlike the case for a SimpleBlock element, the header
    // bits of the Block sub-element of a BlockGroup element do not
    // indicate keyframe status.  The keyframe status is inferred from
    // the absence of reference time sub-elements.)

    return blockg_elem_size;
}
コード例 #5
0
int32 GetIntSize(int64 value) {
  // Doubling the requested value ensures positive values with their high bit
  // set are written with 0-padding to avoid flipping the signedness.
  const uint64 v = (value < 0) ? value ^ -1LL : value;
  return GetUIntSize(2 * v);
}