/* TODO: perhaps this is a poor name for this id serializer helper function */ void Ebml_SerializeBinary(EbmlGlobal *glob, unsigned long class_id, unsigned long bin) { int size; for (size = 4; size > 1; size--) { if (bin & (unsigned int)0x000000ff << ((size - 1) * 8)) break; } Ebml_WriteID(glob, class_id); Ebml_WriteLen(glob, size); Ebml_WriteID(glob, bin); }
//------------------------------------------------------------------ void Ebml_StartSubElement(EbmlGlobal *global, off_t *ebmlLoc, unsigned int class_id) { const uint64_t kEbmlUnknownLength = LITERALU64(0x01FFFFFF, 0xFFFFFFFF); Ebml_WriteID(global, class_id); *ebmlLoc = ftello(global->stream); Ebml_Serialize(global, &kEbmlUnknownLength, sizeof(kEbmlUnknownLength), 8); }
//------------------------------------------------------------------ void Ebml_SerializeUnsigned32(struct EbmlGlobal *global, unsigned int class_id, uint64_t ui) { const unsigned char sizeSerialized = 4 | 0x80; Ebml_WriteID(global, class_id); Ebml_Serialize(global, &sizeSerialized, sizeof(sizeSerialized), 1); Ebml_Serialize(global, &ui, sizeof(ui), 4); }
//------------------------------------------------------------------ void Ebml_SerializeUnsigned64(EbmlGlobal *global, unsigned long class_id, uint64_t ui) { unsigned char sizeSerialized = 8 | 0x80; Ebml_WriteID(global, class_id); Ebml_Serialize(global, &sizeSerialized, sizeof(sizeSerialized), 1); Ebml_Serialize(global, &ui, sizeof(ui), 8); }
void Ebml_SerializeFloat(EbmlGlobal *glob, unsigned long class_id, double d) { unsigned char len = 0x88; Ebml_WriteID(glob, class_id); Ebml_Serialize(glob, &len, sizeof(len), 1); Ebml_Serialize(glob, &d, sizeof(d), 8); }
void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long class_id) { Ebml_WriteID(glob, class_id); assignWide(&ebmlLoc->offset, &glob->offset); //TODO this is always taking 8 bytes, this may need later optimization unsigned long long unknownLen = 0x01FFFFFFFFFFFFFFLLU; Ebml_Serialize(glob, (void *)&unknownLen, 8); //this is a key that says length unknown }
void Ebml_WriteVoid(EbmlGlobal *glob, unsigned long vSize) { unsigned char tmp = 0; unsigned long i = 0; Ebml_WriteID(glob, 0xEC); Ebml_WriteLen(glob, vSize); for (i = 0; i < vSize; i++) { Ebml_Write(glob, &tmp, 1); } }
void writeSimpleBlock(EbmlGlobal *glob, unsigned char trackNumber, short timeCode, int isKeyframe, unsigned char lacingFlag, int discardable, unsigned char *data, unsigned long dataLength) { Ebml_WriteID(glob, SimpleBlock); unsigned long blockLength = 4 + dataLength; blockLength |= 0x10000000; Ebml_Serialize(glob, &blockLength, sizeof(blockLength), 4); trackNumber |= 0x80; Ebml_Write(glob, &trackNumber, 1); Ebml_Serialize(glob, &timeCode, sizeof(timeCode), 2); unsigned char flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable; Ebml_Write(glob, &flags, 1); Ebml_Write(glob, data, dataLength); }
void writeSimpleBlock(EbmlGlobal *glob, unsigned char trackNumber, short timeCode, int isKeyframe, unsigned char lacingFlag, int discardable, unsigned char *data, unsigned long dataLength) { unsigned long blockLength = 4 + dataLength; unsigned char flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable; Ebml_WriteID(glob, SimpleBlock); blockLength |= 0x10000000; // TODO check length < 0x0FFFFFFFF Ebml_Serialize(glob, &blockLength, sizeof(blockLength), 4); trackNumber |= 0x80; // TODO check track nubmer < 128 Ebml_Write(glob, &trackNumber, 1); // Ebml_WriteSigned16(glob, timeCode,2); //this is 3 bytes Ebml_Serialize(glob, &timeCode, sizeof(timeCode), 2); flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable; Ebml_Write(glob, &flags, 1); Ebml_Write(glob, data, dataLength); }
void Ebml_SerializeUnsigned(EbmlGlobal *glob, unsigned long class_id, unsigned long ui) { unsigned char size = 8; /* size in bytes to output */ unsigned char sizeSerialized = 0; unsigned long minVal; Ebml_WriteID(glob, class_id); minVal = 0x7fLU; /* mask to compare for byte size */ for (size = 1; size < 4; size ++) { if (ui < minVal) { break; } minVal <<= 7; } sizeSerialized = 0x80 | size; Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1); Ebml_Serialize(glob, &ui, sizeof(ui), size); }
void write_webm_block(struct EbmlGlobal *glob, const vpx_codec_enc_cfg_t *cfg, const vpx_codec_cx_pkt_t *pkt) { unsigned int block_length; unsigned char track_number; uint16_t block_timecode = 0; unsigned char flags; int64_t pts_ms; int start_cluster = 0, is_keyframe; /* Calculate the PTS of this frame in milliseconds. */ pts_ms = pkt->data.frame.pts * 1000 * (uint64_t)cfg->g_timebase.num / (uint64_t)cfg->g_timebase.den; if (pts_ms <= glob->last_pts_ms) pts_ms = glob->last_pts_ms + 1; glob->last_pts_ms = pts_ms; /* Calculate the relative time of this block. */ if (pts_ms - glob->cluster_timecode > SHRT_MAX) start_cluster = 1; else block_timecode = (uint16_t)pts_ms - glob->cluster_timecode; is_keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY); if (start_cluster || is_keyframe) { if (glob->cluster_open) Ebml_EndSubElement(glob, &glob->startCluster); /* Open the new cluster. */ block_timecode = 0; glob->cluster_open = 1; glob->cluster_timecode = (uint32_t)pts_ms; glob->cluster_pos = ftello(glob->stream); Ebml_StartSubElement(glob, &glob->startCluster, Cluster); Ebml_SerializeUnsigned(glob, Timecode, glob->cluster_timecode); /* Save a cue point if this is a keyframe. */ if (is_keyframe) { struct cue_entry *cue, *new_cue_list; new_cue_list = realloc(glob->cue_list, (glob->cues + 1) * sizeof(struct cue_entry)); if (new_cue_list) glob->cue_list = new_cue_list; else fatal("Failed to realloc cue list."); cue = &glob->cue_list[glob->cues]; cue->time = glob->cluster_timecode; cue->loc = glob->cluster_pos; glob->cues++; } } /* Write the Simple Block. */ Ebml_WriteID(glob, SimpleBlock); block_length = (unsigned int)pkt->data.frame.sz + 4; block_length |= 0x10000000; Ebml_Serialize(glob, &block_length, sizeof(block_length), 4); track_number = 1; track_number |= 0x80; Ebml_Write(glob, &track_number, 1); Ebml_Serialize(glob, &block_timecode, sizeof(block_timecode), 2); flags = 0; if (is_keyframe) flags |= 0x80; if (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) flags |= 0x08; Ebml_Write(glob, &flags, 1); Ebml_Write(glob, pkt->data.frame.buf, (unsigned int)pkt->data.frame.sz); }
//------------------------------------------------------------------ void Ebml_SerializeString(EbmlGlobal *global, unsigned long class_id, const char *s) { Ebml_WriteID(global, class_id); Ebml_WriteString(global, s); }
void Ebml_SerializeData(EbmlGlobal *glob, unsigned long class_id, unsigned char *data, unsigned long data_length) { Ebml_WriteID(glob, class_id); Ebml_WriteLen(glob, data_length); Ebml_Write(glob, data, data_length); }
void Ebml_SerializeUTF8(EbmlGlobal *glob, unsigned long class_id, wchar_t *s) { Ebml_WriteID(glob, class_id); Ebml_WriteUTF8(glob, s); }