u32 gf_rtp_build_au_hdr_write(GP_RTPPacketizer *builder, u32 PayloadSize, u32 RTP_TS)
{
	u32 nbBits = 0;
	s32 delta;

	/*selective encryption*/
	if (builder->flags & GP_RTP_PCK_SELECTIVE_ENCRYPTION) {
		gf_bs_write_int(builder->pck_hdr, builder->is_encrypted, 1);
		gf_bs_write_int(builder->pck_hdr, 0, 7);
		nbBits = 8;
	}
	/*IV*/
	if (builder->first_sl_in_rtp) {
		if (builder->slMap.IV_length) {
			gf_bs_write_long_int(builder->pck_hdr, builder->IV, 8*builder->slMap.IV_length);
			nbBits += 8*builder->slMap.IV_length;
		}
	} else if (builder->slMap.IV_delta_length) {
		/*NOT SUPPORTED!!! this only applies to interleaving*/
	}
	/*key*/
	if (builder->slMap.KI_length) {
		if (builder->first_sl_in_rtp || (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU)) {
			if (builder->key_indicator) gf_bs_write_data(builder->pck_hdr, builder->key_indicator, builder->slMap.KI_length);
			else gf_bs_write_int(builder->pck_hdr, 0, 8*builder->slMap.KI_length);
			nbBits += 8*builder->slMap.KI_length;
		}
	}


	/*size length*/
	if (builder->slMap.ConstantSize) {
		if (PayloadSize != builder->slMap.ConstantSize) return nbBits;
	} else if (builder->slMap.SizeLength) {
		/*write the AU size - if not enough bytes (real-time cases) set size to 0*/
		if (builder->sl_header.accessUnitLength >= (1<<builder->slMap.SizeLength)) {
			gf_bs_write_int(builder->pck_hdr, 0, builder->slMap.SizeLength);
		} else {
			gf_bs_write_int(builder->pck_hdr, builder->sl_header.accessUnitLength, builder->slMap.SizeLength);
		}
		nbBits += builder->slMap.SizeLength;
	}
	/*AU index*/
	if (builder->first_sl_in_rtp) {
		if (builder->slMap.IndexLength) {
			gf_bs_write_int(builder->pck_hdr, builder->sl_header.AU_sequenceNumber, builder->slMap.IndexLength);
			nbBits += builder->slMap.IndexLength;
		}
	} else {
		if (builder->slMap.IndexDeltaLength) {
			//check interleaving, otherwise force default (which is currently always the case)
			delta = builder->sl_header.AU_sequenceNumber - builder->last_au_sn;
			delta -= 1;
			gf_bs_write_int(builder->pck_hdr, delta, builder->slMap.IndexDeltaLength);
			nbBits += builder->slMap.IndexDeltaLength;
		}
	}

	/*CTS Flag*/
	if (builder->slMap.CTSDeltaLength) {
		if (builder->first_sl_in_rtp) {
			builder->sl_header.compositionTimeStampFlag = 0;
			builder->sl_header.compositionTimeStamp = RTP_TS;
		}
		gf_bs_write_int(builder->pck_hdr, builder->sl_header.compositionTimeStampFlag, 1);
		nbBits += 1;
	}
	/*CTS*/
	if (builder->sl_header.compositionTimeStampFlag) {
		delta = (u32) builder->sl_header.compositionTimeStamp - RTP_TS;
		gf_bs_write_int(builder->pck_hdr, delta, builder->slMap.CTSDeltaLength);
		nbBits += builder->slMap.CTSDeltaLength;
	}
	/*DTS Flag*/
	if (builder->slMap.DTSDeltaLength) {
		gf_bs_write_int(builder->pck_hdr, builder->sl_header.decodingTimeStampFlag, 1);
		nbBits += 1;
	}
	/*DTS*/
	if (builder->sl_header.decodingTimeStampFlag) {
		delta = (u32) (builder->sl_header.compositionTimeStamp - builder->sl_header.decodingTimeStamp);
		gf_bs_write_int(builder->pck_hdr, delta, builder->slMap.DTSDeltaLength);
		nbBits += builder->slMap.DTSDeltaLength;
	}
	/*RAP indication*/
	if (builder->slMap.RandomAccessIndication) {
		gf_bs_write_int(builder->pck_hdr, builder->sl_header.randomAccessPointFlag, 1);
		nbBits ++;
	}
	/*stream state - write AUSeqNum*/
	if (builder->slMap.StreamStateIndication) {
		gf_bs_write_int(builder->pck_hdr, builder->sl_header.AU_sequenceNumber, builder->slMap.StreamStateIndication);
		nbBits += builder->slMap.StreamStateIndication;
	}

	return nbBits;
}