/* * Encode data from g_virstor_metadata structure into a endian-independant * byte stream. */ void virstor_metadata_encode(struct g_virstor_metadata *md, unsigned char *data) { bin_stream_t bs; bs_open(&bs, data); bs_write_buf(&bs, md->md_magic, sizeof(md->md_magic)); bs_write_u32(&bs, md->md_version); bs_write_buf(&bs, md->md_name, sizeof(md->md_name)); bs_write_u64(&bs, md->md_virsize); bs_write_u32(&bs, md->md_chunk_size); bs_write_u32(&bs, md->md_id); bs_write_u16(&bs, md->md_count); bs_write_buf(&bs, md->provider, sizeof(md->provider)); bs_write_u16(&bs, md->no); bs_write_u64(&bs, md->provsize); bs_write_u32(&bs, md->chunk_count); bs_write_u32(&bs, md->chunk_next); bs_write_u16(&bs, md->chunk_reserved); bs_write_u16(&bs, md->flags); }
int pes_header_write(pes_header_t *ph, bs_t *b) { // TODO: add support for PES-level stuffing int start_pos = bs_pos(b); bs_write_u24(b, PES_PACKET_START_CODE_PREFIX); bs_write_u8(b, ph->stream_id); bs_write_u16(b, ph->PES_packet_length); if (HAS_PES_HEADER(ph->stream_id)) { bs_write_u(b, 2, 0x02); bs_write_u(b, 2, ph->PES_scrambling_control); bs_write_u1(b, ph->PES_priority); bs_write_u1(b, ph->data_alignment_indicator); bs_write_u1(b, ph->copyright); bs_write_u1(b, ph->original_or_copy); bs_write_u(b, 2, ph->PTS_DTS_flags); bs_write_u1(b, ph->ESCR_flag); bs_write_u1(b, ph->ES_rate_flag); bs_write_u1(b, ph->DSM_trick_mode_flag); bs_write_u1(b, ph->additional_copy_info_flag); bs_write_u1(b, ph->PES_CRC_flag); bs_write_u1(b, ph->PES_extension_flag); bs_write_u8(b, ph->PES_header_data_length); if (ph->PTS_DTS_flags & PES_PTS_FLAG) { bs_write_u(b, 4, 0x02); bs_write_90khz_timestamp(b, ph->PTS); } if (ph->PTS_DTS_flags & PES_DTS_FLAG) { bs_write_u(b, 4, 0x01); bs_write_90khz_timestamp(b, ph->DTS); } if (ph->ESCR_flag) { bs_write_reserved(b, 2); bs_write_90khz_timestamp(b, ph->ESCR_base); bs_write_u(b, 9, ph->ESCR_extension); bs_write_marker_bit(b); } if (ph->ES_rate_flag) { bs_write_marker_bit(b); bs_write_u(b, 22, ph->ES_rate); bs_write_marker_bit(b); } if (ph->DSM_trick_mode_flag) { bs_write_u(b, 3, ph->trick_mode_control); switch (ph->trick_mode_control) { case PES_DSM_TRICK_MODE_CTL_FAST_FORWARD: case PES_DSM_TRICK_MODE_CTL_FAST_REVERSE: bs_write_u(b, 2, ph->field_id); bs_write_u1(b, ph->intra_slice_refresh); bs_write_u(b, 2, ph->frequency_truncation); break; case PES_DSM_TRICK_MODE_CTL_SLOW_MOTION: case PES_DSM_TRICK_MODE_CTL_SLOW_REVERSE: bs_write_u(b, 5, ph->rep_cntrl); break; case PES_DSM_TRICK_MODE_CTL_FREEZE_FRAME: bs_write_u(b, 2, ph->field_id); bs_write_reserved(b, 3); break; default: bs_write_reserved(b, 5); break; } } if (ph->additional_copy_info_flag) { bs_write_marker_bit(b); bs_write_u(b, 7, ph->additional_copy_info); } if (ph->PES_CRC_flag) { bs_write_u16(b, ph->previous_PES_packet_CRC); } if (ph->PES_extension_flag) { bs_write_u1(b, ph->PES_private_data_flag); bs_write_u1(b, 0); // pack_header not supported bs_write_u1(b, ph->program_packet_sequence_counter_flag); bs_write_u1(b, ph->PSTD_buffer_flag); bs_write_reserved(b, 3); bs_write_u1(b, ph->PES_extension_flag_2); if (ph->PES_private_data_flag) { bs_write_bytes(b, ph->PES_private_data, 16); } if (ph->program_packet_sequence_counter_flag) { bs_write_marker_bit(b); bs_write_u(b, 7, ph->program_packet_sequence_counter); bs_write_marker_bit(b); bs_write_u1(b, ph->MPEG1_MPEG2_identifier); bs_write_u(b, 6, ph->original_stuff_length); } if (ph->PSTD_buffer_flag) { bs_write_u(b, 2, 0x01); bs_write_u1(b, ph->PSTD_buffer_scale); bs_write_u(b, 13, ph->PSTD_buffer_size); } if (ph->PES_extension_flag_2) { bs_write_marker_bit(b); bs_write_u(b, 7, ph->PES_extension_field_length); bs_write_u1(b, ph->stream_id_extension_flag); if (!ph->stream_id_extension_flag) { bs_write_u(b, 7, ph->stream_id_extension); } else { bs_write_reserved(b, 6); bs_write_u1(b, ph->tref_extension_flag); if (ph->tref_extension_flag) { bs_write_reserved(b, 4); bs_write_90khz_timestamp(b, ph->TREF); } } } } } return (bs_pos(b) - start_pos); }