Beispiel #1
0
GF_Err senc_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 sample_count;
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, ptr->flags);

	sample_count = gf_list_count(ptr->samp_aux_info);
	gf_bs_write_u32(bs, sample_count);
	if (sample_count) {
		u32 i, j;

		e = store_senc_info(ptr, bs);
		if (e) return e;

		for (i = 0; i < sample_count; i++) {
			GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
			//for cbcs scheme, IV_size is 0, constant IV shall be used. It is written in tenc box rather than in sai
			if (sai->IV_size)
				gf_bs_write_data(bs, (char *)sai->IV, sai->IV_size);
			if (ptr->flags & 0x00000002) {
				gf_bs_write_u16(bs, sai->subsample_count);
				for (j = 0; j < sai->subsample_count; j++) {
					gf_bs_write_u16(bs, sai->subsamples[j].bytes_clear_data);
					gf_bs_write_u32(bs, sai->subsamples[j].bytes_encrypted_data);
				}
			}
		}
	}
	return GF_OK;
}
Beispiel #2
0
GF_Err piff_tenc_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, ptr->flags);

	gf_bs_write_int(bs, ptr->AlgorithmID, 24);
	gf_bs_write_u8(bs, ptr->IV_size);
	gf_bs_write_data(bs, (char *) ptr->KID, 16);
	return GF_OK;
}
Beispiel #3
0
GF_Err piff_pssh_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, ptr->flags);

	gf_bs_write_data(bs, (char *) ptr->SystemID, 16);
	gf_bs_write_u32(bs, ptr->private_data_size);
	gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size);
	return GF_OK;
}
Beispiel #4
0
GF_Err gf_isom_rewrite_text_sample(GF_ISOSample *samp, u32 sampleDescriptionIndex, u32 sample_dur)
{
	GF_BitStream *bs;
	u32 pay_start, txt_size;
	Bool is_utf_16 = 0;
	if (!samp || !samp->data || !samp->dataLength) return GF_OK;

	bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_READ);
	txt_size = gf_bs_read_u16(bs);
	gf_bs_del(bs);

	/*remove BOM*/
	pay_start = 2;
	if (txt_size>2) {
		/*seems 3GP only accepts BE UTF-16 (no LE, no UTF32)*/
		if (((u8) samp->data[2]==(u8) 0xFE) && ((u8)samp->data[3]==(u8) 0xFF)) {
			is_utf_16 = 1;
			pay_start = 4;
			txt_size -= 2;
		}
	}

	/*rewrite as TTU(1)*/
	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
	gf_bs_write_int(bs, is_utf_16, 1);
	gf_bs_write_int(bs, 0, 4);
	gf_bs_write_int(bs, 1, 3);
	gf_bs_write_u16(bs, 8 + samp->dataLength - pay_start);
	gf_bs_write_u8(bs, sampleDescriptionIndex + SAMPLE_INDEX_OFFSET);
	gf_bs_write_u24(bs, sample_dur);
	/*write text size*/
	gf_bs_write_u16(bs, txt_size);
	if (txt_size) gf_bs_write_data(bs, samp->data + pay_start, samp->dataLength - pay_start);

	gf_free(samp->data);
	samp->data = NULL;
	gf_bs_get_content(bs, &samp->data, &samp->dataLength);
	gf_bs_del(bs);
	return GF_OK;
}
Beispiel #5
0
GF_Err piff_psec_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, ptr->flags);

	if (ptr->flags & 1) {
		gf_bs_write_int(bs, ptr->AlgorithmID, 24);
		gf_bs_write_u8(bs, ptr->IV_size);
		gf_bs_write_data(bs, (char *) ptr->KID, 16);
	}
	gf_bs_write_u32(bs, ptr->sample_count);
	if (ptr->cenc_data && ptr->cenc_data_size) {
		gf_bs_write_data(bs, ptr->cenc_data, ptr->cenc_data_size);
	}
	return GF_OK;
}
Beispiel #6
0
GF_Err piff_psec_Write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 sample_count;
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, ptr->flags);

	if (ptr->flags & 1) {
		gf_bs_write_int(bs, ptr->AlgorithmID, 24);
		gf_bs_write_u8(bs, ptr->IV_size);
		gf_bs_write_data(bs, (char *) ptr->KID, 16);
	}
	sample_count = gf_list_count(ptr->samp_aux_info);
	gf_bs_write_u32(bs, sample_count);
	if (sample_count) {
		u32 i, j;
		e = store_senc_info((GF_SampleEncryptionBox *)ptr, bs);
		if (e) return e;

		for (i = 0; i < sample_count; i++) {
			GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
			if (! sai->IV_size) continue;
			gf_bs_write_data(bs, (char *)sai->IV, sai->IV_size);
			gf_bs_write_u16(bs, sai->subsample_count);
			for (j = 0; j < sai->subsample_count; j++) {
				gf_bs_write_u16(bs, sai->subsamples[j].bytes_clear_data);
				gf_bs_write_u32(bs, sai->subsamples[j].bytes_encrypted_data);
			}
		}
	}
	return GF_OK;
}
Beispiel #7
0
GF_Err gf_isom_get_ttxt_esd(GF_MediaBox *mdia, GF_ESD **out_esd)
{
	GF_BitStream *bs;
	u32 count, i;
	Bool has_v_info;
	GF_List *sampleDesc;
	GF_ESD *esd;
	GF_TrackBox *tk;

	*out_esd = NULL;
	sampleDesc = mdia->information->sampleTable->SampleDescription->boxList;
	count = gf_list_count(sampleDesc);
	if (!count) return GF_ISOM_INVALID_MEDIA;
	
	esd = gf_odf_desc_esd_new(2);
	esd->decoderConfig->streamType = GF_STREAM_TEXT;
	esd->decoderConfig->objectTypeIndication = 0x08;

	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);


	/*Base3GPPFormat*/
	gf_bs_write_u8(bs, 0x10);
	/*MPEGExtendedFormat*/
	gf_bs_write_u8(bs, 0x10);
	/*profileLevel*/
	gf_bs_write_u8(bs, 0x10);
	gf_bs_write_u24(bs, mdia->mediaHeader->timeScale);
	gf_bs_write_int(bs, 0, 1);	/*no alt formats*/
	gf_bs_write_int(bs, 2, 2);	/*only out-of-band-band sample desc*/
	gf_bs_write_int(bs, 1, 1);	/*we will write sample desc*/

	/*write v info if any visual track in this movie*/
	has_v_info = 0;
	i=0;
	while ((tk = (GF_TrackBox*)gf_list_enum(mdia->mediaTrack->moov->trackList, &i))) {
		if (tk->Media->handler && (tk->Media->handler->handlerType == GF_ISOM_MEDIA_VISUAL)) {
			has_v_info = 1;
		}
	}
	gf_bs_write_int(bs, has_v_info, 1);

	gf_bs_write_int(bs, 0, 3);	/*reserved, spec doesn't say the values*/
	gf_bs_write_u8(bs, mdia->mediaTrack->Header->layer);
	gf_bs_write_u16(bs, mdia->mediaTrack->Header->width>>16);
	gf_bs_write_u16(bs, mdia->mediaTrack->Header->height>>16);

	/*write desc*/
	gf_bs_write_u8(bs, count);
	for (i=0; i<count; i++) {
		GF_Tx3gSampleEntryBox *a;
		a = (GF_Tx3gSampleEntryBox *) gf_list_get(sampleDesc, i);
		if ((a->type != GF_ISOM_BOX_TYPE_TX3G) && (a->type != GF_ISOM_BOX_TYPE_TEXT) ) continue;
		gf_isom_write_tx3g(a, bs, i+1, SAMPLE_INDEX_OFFSET);
	}
	if (has_v_info) {
		u32 trans;
		/*which video shall we pick for MPEG-4, and how is the associations indicated in 3GP ???*/
		gf_bs_write_u16(bs, 0);
		gf_bs_write_u16(bs, 0);
		trans = mdia->mediaTrack->Header->matrix[6]; trans >>= 16;
		gf_bs_write_u16(bs, trans);
		trans = mdia->mediaTrack->Header->matrix[7]; trans >>= 16;
		gf_bs_write_u16(bs, trans);
	}

	gf_bs_get_content(bs, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength);
	gf_bs_del(bs);
	*out_esd = esd;
	return GF_OK;
}
Beispiel #8
0
GF_Err gp_rtp_builder_do_tx3g(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration, u8 descIndex)
{
	GF_BitStream *bs;
	char *hdr;
	u32 samp_size, txt_size, pay_start, hdr_size, txt_done, cur_frag, nb_frag;
	Bool is_utf_16 = 0;

	if (!data) {
		/*flush packet*/
		if (builder->bytesInPacket) {
			builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);
			builder->bytesInPacket = 0;
		}
		return GF_OK;
	}
	/*cfg packet*/
	txt_size = data[0]; txt_size <<= 8; txt_size |= (unsigned char) data[1];
	/*remove BOM*/
	pay_start = 2;
	if (txt_size>2) {
		/*seems 3GP only accepts BE UTF-16 (no LE, no UTF32)*/
		if (((u8) data[2]==(u8) 0xFE) && ((u8) data[3]==(u8) 0xFF)) {
			is_utf_16 = 1;
			pay_start = 4;
			txt_size -= 2;
		}
	}
	samp_size = data_size - pay_start;

	/*if TTU does not fit in packet flush packet*/
	if (builder->bytesInPacket && (builder->bytesInPacket + 3 + 6 + samp_size > builder->Path_MTU)) {
		builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);
		builder->bytesInPacket = 0;
	}

	/*first TTU in packet*/
	if (!builder->bytesInPacket) {
		builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp;
		builder->rtp_header.Marker = 1;
		builder->rtp_header.SequenceNumber += 1;
		builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);
	}
	/*fits entirely*/
	if (builder->bytesInPacket + 3 + 6 + samp_size <= builder->Path_MTU) {
		bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
		gf_bs_write_int(bs, is_utf_16, 1);
		gf_bs_write_int(bs, 0, 4);
		gf_bs_write_int(bs, 1, 3);
		gf_bs_write_u16(bs, 8 + samp_size);
		gf_bs_write_u8(bs, descIndex);
		gf_bs_write_u24(bs, duration);
		gf_bs_write_u16(bs, txt_size);
		gf_bs_get_content(bs, &hdr, &hdr_size);
		gf_bs_del(bs);
		builder->OnData(builder->cbk_obj, (char *) hdr, hdr_size, 0);
		builder->bytesInPacket += hdr_size;
		gf_free(hdr);

		if (txt_size) {
			if (builder->OnDataReference) {
				builder->OnDataReference(builder->cbk_obj, samp_size, pay_start);
			} else {
				builder->OnData(builder->cbk_obj, data + pay_start, samp_size, 0);
			}
			builder->bytesInPacket += samp_size;
		}
		/*disable aggregation*/
		if (!(builder->flags & GP_RTP_PCK_USE_MULTI)) {
			builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);
			builder->bytesInPacket = 0;
		}
		return GF_OK;
	}
	/*doesn't fit and already data, flush packet*/
	if (builder->bytesInPacket) {
		builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);
		builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp;
		/*split unit*/
		builder->rtp_header.Marker = 0;
		builder->rtp_header.SequenceNumber += 1;
		builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);
		builder->bytesInPacket = 0;
	}
	/*write all type2 units (text only) - FIXME: split at char boundaries, NOT SUPPORTED YET*/
	txt_done = 0;
	nb_frag = 1;
	/*all fragments needed for Type2 units*/
	while (txt_done + (builder->Path_MTU-10) < txt_size) {
		txt_done += (builder->Path_MTU-10);
		nb_frag += 1;
	}
	/*all fragments needed for Type3/4 units*/
	txt_done = txt_size;
	while (txt_done + (builder->Path_MTU-7) < samp_size) {
		txt_done += (builder->Path_MTU-7);
		nb_frag += 1;
	}


	cur_frag = 0;
	txt_done = 0;
	while (txt_done<txt_size) {
		u32 size;
		if (txt_done + (builder->Path_MTU-10) < txt_size) {
			size = builder->Path_MTU-10;
		} else {
			size = txt_size - txt_done;
		}

		bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
		gf_bs_write_int(bs, is_utf_16, 1);
		gf_bs_write_int(bs, 0, 4);
		gf_bs_write_int(bs, 2, 3);
		gf_bs_write_u16(bs, 9 + size);
		gf_bs_write_int(bs, nb_frag, 4);
		gf_bs_write_int(bs, cur_frag, 4);
		gf_bs_write_u24(bs, duration);
		gf_bs_write_u8(bs, descIndex);
		/*SLEN is the full original length minus text len and BOM (put here for buffer allocation purposes)*/
		gf_bs_write_u16(bs, samp_size);
		gf_bs_get_content(bs, &hdr, &hdr_size);
		gf_bs_del(bs);
		builder->OnData(builder->cbk_obj, (char *) hdr, hdr_size, 0);
		builder->bytesInPacket += hdr_size;
		gf_free(hdr);

		if (builder->OnDataReference) {
			builder->OnDataReference(builder->cbk_obj, size, pay_start + txt_done);
		} else {
			builder->OnData(builder->cbk_obj, data + pay_start + txt_done, size, 0);
		}
		builder->bytesInPacket += size;
		cur_frag++;

		/*flush packet*/
		if (cur_frag == nb_frag) {
			txt_done = txt_size;
			if (pay_start + txt_done == data_size) {
				builder->rtp_header.Marker = 1;
				builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);
				builder->bytesInPacket = 0;
			}
		} else {
			txt_done += size;
			builder->rtp_header.Marker = 0;
			builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);
			builder->rtp_header.SequenceNumber += 1;
			builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);
			builder->bytesInPacket = 0;
		}
	}

	txt_done = txt_size;

	/*write all modifiers - OPT: split at modifiers boundaries*/
	while (txt_done<samp_size) {
		u32 size, type;
		type = (txt_done == txt_size) ? 3 : 4;

		if (txt_done + (builder->Path_MTU-7) < samp_size) {
			size = builder->Path_MTU-10;
		} else {
			size = samp_size - txt_done;
		}

		bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
		gf_bs_write_int(bs, is_utf_16, 1);
		gf_bs_write_int(bs, 0, 4);
		gf_bs_write_int(bs, type, 3);
		gf_bs_write_u16(bs, 6 + size);
		gf_bs_write_int(bs, nb_frag, 4);
		gf_bs_write_int(bs, cur_frag, 4);
		gf_bs_write_u24(bs, duration);

		gf_bs_get_content(bs, &hdr, &hdr_size);
		gf_bs_del(bs);
		builder->OnData(builder->cbk_obj, (char *) hdr, hdr_size, 0);
		builder->bytesInPacket += hdr_size;
		gf_free(hdr);

		if (builder->OnDataReference) {
			builder->OnDataReference(builder->cbk_obj, size, pay_start + txt_done);
		} else {
			builder->OnData(builder->cbk_obj, data + pay_start + txt_done, size, 0);
		}
		builder->bytesInPacket += size;
		cur_frag++;
		if (cur_frag==nb_frag) {
			builder->rtp_header.Marker = 1;
			builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);
			builder->bytesInPacket = 0;
		} else {
			builder->rtp_header.Marker = 0;
			builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);
			builder->rtp_header.SequenceNumber += 1;
			builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);
			builder->bytesInPacket = 0;
		}
		txt_done += size;
	}
	return GF_OK;
}