Beispiel #1
0
/*
 * 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);
}