u32 gf_media_avc_reformat_sei(char *buffer, u32 nal_size, AVCState *avc)
{
	u32 ptype, psize, hdr, written, var;
	u64 start;
	char *new_buffer;
	GF_BitStream *bs;
	char *sei_without_emulation_bytes = NULL;
	u32 sei_without_emulation_bytes_size = 0;

	hdr = buffer[0];
	if ((hdr & 0x1F) != GF_AVC_NALU_SEI) return 0;

	/*PPS still contains emulation bytes*/
	sei_without_emulation_bytes = gf_malloc(nal_size + 1/*for SEI null string termination*/);
	sei_without_emulation_bytes_size = avc_remove_emulation_bytes(buffer, sei_without_emulation_bytes, nal_size);

	bs = gf_bs_new(sei_without_emulation_bytes, sei_without_emulation_bytes_size, GF_BITSTREAM_READ);
	gf_bs_read_int(bs, 8);

	new_buffer = (char*)gf_malloc(sizeof(char)*nal_size);
	new_buffer[0] = (char) hdr;
	written = 1;
	/*parse SEI*/
	while (gf_bs_available(bs)) {
		Bool do_copy;
		ptype = 0;
		while (gf_bs_peek_bits(bs, 8, 0)==0xFF) {
			gf_bs_read_int(bs, 8);
			ptype += 255;
		}
		ptype += gf_bs_read_int(bs, 8);
		psize = 0;
		while (gf_bs_peek_bits(bs, 8, 0)==0xFF) {
			gf_bs_read_int(bs, 8);
			psize += 255;
		}
		psize += gf_bs_read_int(bs, 8);

		start = gf_bs_get_position(bs);

		do_copy = 1;

		if (start+psize >= nal_size) {
			if (written == 1) written = 0;
			GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[avc-h264] SEI user message type %d size error (%d but %d remain), skiping %sSEI message\n", ptype, psize, nal_size-start, written ? "end of " : ""));
			break;
		}
		switch (ptype) {
		/*remove SEI messages forbidden in MP4*/
		case 3: /*filler data*/
		case 10: /*sub_seq info*/
		case 11: /*sub_seq_layer char*/
		case 12: /*sub_seq char*/
			do_copy = 0;
			break;
		case 5: /*user unregistered */
		{
			char prev;
			prev = sei_without_emulation_bytes[start+psize+1];
			sei_without_emulation_bytes[start+psize+1] = 0;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[avc-h264] SEI user message %s\n", sei_without_emulation_bytes+start+16));
			sei_without_emulation_bytes[start+psize+1] = prev;
		}
		break;

		case 6: /*recovery point*/
		{
			GF_BitStream *rp_bs = gf_bs_new(sei_without_emulation_bytes + start, psize, GF_BITSTREAM_READ);
			avc_parse_recovery_point_sei(rp_bs, avc);
			gf_bs_del(rp_bs);
		}
		break;

		case 1: /*pic_timing*/
		{
			GF_BitStream *pt_bs = gf_bs_new(sei_without_emulation_bytes + start, psize, GF_BITSTREAM_READ);
			avc_parse_pic_timing_sei(pt_bs, avc);
			gf_bs_del(pt_bs);
		}
		break;

		case 0: /*buffering period*/
		case 2: /*pan scan rect*/
		case 4: /*user registered ITU t35*/
		case 7: /*def_rec_pic_marking_repetition*/
		case 8: /*spare_pic*/
		case 9: /*scene info*/
		case 13: /*full frame freeze*/
		case 14: /*full frame freeze release*/
		case 15: /*full frame snapshot*/
		case 16: /*progressive refinement segment start*/
		case 17: /*progressive refinement segment end*/
		case 18: /*motion constrained slice group*/
			break;
		default: /*reserved*/
			do_copy = 0;
			break;
		}

		if (do_copy) {
			var = ptype;
			while (var>=255) {
				new_buffer[written] = (char) 0xff;
				written++;
				var-=255;
			}
			new_buffer[written] = (char) var;
			written++;
			var = psize;
			while (var>=255) {
				new_buffer[written] = (char) 0xff;
				written++;
				var-=255;
			}
			new_buffer[written] = (char) var;
			written++;
			memcpy(new_buffer+written, sei_without_emulation_bytes+start, sizeof(char) * psize);
			written += psize;
		}

		gf_bs_skip_bytes(bs, (u64) psize);
		gf_bs_align(bs);
		if (gf_bs_available(bs)<=2) {
			if (gf_bs_peek_bits(bs, 8, 0)==0x80) {
				new_buffer[written] = (char) 0x80;
				written += 1;
			}
			break;
		}
	}
	gf_bs_del(bs);
	gf_free(sei_without_emulation_bytes);

	if (written) {
		var = avc_emulation_bytes_add_count(new_buffer, written);
		if (var) {
			if (written+var<=nal_size) {
				written = avc_add_emulation_bytes(new_buffer, buffer, written);
			} else {
				written = 0;
			}
		} else {
			if (written<=nal_size) {
				memcpy(buffer, new_buffer, sizeof(char)*written);
			} else {
				written = 0;
			}
		}
	}
	gf_free(new_buffer);

	/*if only hdr written ignore*/
	return (written>1) ? written : 0;
}