示例#1
0
static void AAC_OnLiveData(AACReader *read, char *data, u32 data_size)
{
	u32 pos;
	Bool sync;
	GF_BitStream *bs;
	ADTSHeader hdr;
	
	read->data = realloc(read->data, sizeof(char)*(read->data_size+data_size) );
	memcpy(read->data + read->data_size, data, sizeof(char)*data_size);
	read->data_size += data_size;

	if (read->needs_connection) {
		read->needs_connection = 0;
		bs = gf_bs_new(read->data, read->data_size, GF_BITSTREAM_READ);
		sync = ADTS_SyncFrame(bs, 0, &hdr);
		gf_bs_del(bs);
		if (!sync) return;
		read->nb_ch = hdr.nb_ch;
		read->prof = hdr.profile;
		read->sr_idx = hdr.sr_idx;
		read->oti = hdr.is_mp2 ? read->prof+0x66-1 : 0x40;
		read->sample_rate = GF_M4ASampleRates[read->sr_idx];
		read->is_live = 1;
		memset(&read->sl_hdr, 0, sizeof(GF_SLHeader));
		gf_term_on_connect(read->service, NULL, GF_OK);
		AAC_SetupObject(read);
	}
	if (!read->ch) return;

	/*need a full adts header*/
	if (read->data_size<=7) return;

	bs = gf_bs_new(read->data, read->data_size, GF_BITSTREAM_READ);
	hdr.frame_size = pos = 0;
	while (ADTS_SyncFrame(bs, 0, &hdr)) {
		pos = (u32) gf_bs_get_position(bs);
		read->sl_hdr.accessUnitStartFlag = 1;
		read->sl_hdr.accessUnitEndFlag = 1;
		read->sl_hdr.AU_sequenceNumber++;
		read->sl_hdr.compositionTimeStampFlag = 1;
		read->sl_hdr.compositionTimeStamp += 1024;
		gf_term_on_sl_packet(read->service, read->ch, read->data + pos, hdr.frame_size, &read->sl_hdr, GF_OK);
		gf_bs_skip_bytes(bs, hdr.frame_size);
	}

	pos = (u32) gf_bs_get_position(bs);
	gf_bs_del(bs);

	if (pos) {
		char *d;
		read->data_size -= pos;
		d = malloc(sizeof(char) * read->data_size);
		memcpy(d, read->data + pos, sizeof(char) * read->data_size);
		free(read->data);
		read->data = d;
	}
	AAC_RegulateDataRate(read);
}
示例#2
0
static void AC3_OnLiveData(AC3Reader *read, const char *data, u32 data_size)
{
	u64 pos;
	Bool sync;
	GF_BitStream *bs;
	GF_AC3Header hdr;

	memset(&hdr, 0, sizeof(GF_AC3Header));

	read->data = gf_realloc(read->data, sizeof(char)*(read->data_size+data_size) );
	memcpy(read->data + read->data_size, data, sizeof(char)*data_size);
	read->data_size += data_size;

	if (read->needs_connection) {
		read->needs_connection = 0;
		bs = gf_bs_new((char *) read->data, read->data_size, GF_BITSTREAM_READ);
		sync = gf_ac3_parser_bs(bs, &hdr, GF_TRUE);
		gf_bs_del(bs);
		if (!sync) return;
		read->nb_ch = hdr.channels;
		read->sample_rate = hdr.sample_rate;
		read->is_live = 1;
		memset(&read->sl_hdr, 0, sizeof(GF_SLHeader));
		gf_service_connect_ack(read->service, NULL, GF_OK);
		AC3_SetupObject(read);
	}
	if (!read->ch) return;

	/*need a full ac3 header*/
	if (read->data_size<=7) return;

	bs = gf_bs_new((char *) read->data, read->data_size, GF_BITSTREAM_READ);
	hdr.framesize = 0;
	pos = 0;
	while (gf_ac3_parser_bs(bs, &hdr, GF_FALSE)) {
		pos = gf_bs_get_position(bs);
		read->sl_hdr.accessUnitStartFlag = 1;
		read->sl_hdr.accessUnitEndFlag = 1;
		read->sl_hdr.AU_sequenceNumber++;
		read->sl_hdr.compositionTimeStampFlag = 1;
		read->sl_hdr.compositionTimeStamp += 1536;
		gf_service_send_packet(read->service, read->ch, (char *) read->data + pos, hdr.framesize, &read->sl_hdr, GF_OK);
		gf_bs_skip_bytes(bs, hdr.framesize);
	}

	pos = gf_bs_get_position(bs);
	gf_bs_del(bs);

	if (pos) {
		u8 *d;
		read->data_size -= (u32) pos;
		d = gf_malloc(sizeof(char) * read->data_size);
		memcpy(d, read->data + pos, sizeof(char) * read->data_size);
		gf_free(read->data);
		read->data = d;
	}
	AC3_RegulateDataRate(read);
}
示例#3
0
static Bool ADTS_SyncFrame(GF_BitStream *bs, Bool is_complete, ADTSHeader *hdr)
{
	u32 val, pos, start_pos;

	start_pos = (u32) gf_bs_get_position(bs);
	while (gf_bs_available(bs)) {
		val = gf_bs_read_u8(bs);
		if (val!=0xFF) continue;
		val = gf_bs_read_int(bs, 4);
		if (val != 0x0F) {
			gf_bs_read_int(bs, 4);
			continue;
		}
		hdr->is_mp2 = gf_bs_read_int(bs, 1);
		gf_bs_read_int(bs, 2);
		hdr->no_crc = gf_bs_read_int(bs, 1);
		pos = (u32) gf_bs_get_position(bs) - 2;

		hdr->profile = 1 + gf_bs_read_int(bs, 2);
		hdr->sr_idx = gf_bs_read_int(bs, 4);
		gf_bs_read_int(bs, 1);
		hdr->nb_ch = gf_bs_read_int(bs, 3);
		gf_bs_read_int(bs, 4);
		hdr->frame_size = gf_bs_read_int(bs, 13);
		gf_bs_read_int(bs, 11);
		gf_bs_read_int(bs, 2);
		hdr->hdr_size = 7;
		if (!hdr->no_crc) {
			gf_bs_read_u16(bs);
			hdr->hdr_size = 9;
		}
		if (hdr->frame_size < hdr->hdr_size) {
			gf_bs_seek(bs, pos+1);
			continue;
		}
		hdr->frame_size -= hdr->hdr_size;
		if (is_complete && (gf_bs_available(bs) == hdr->frame_size)) return 1;
		else if (gf_bs_available(bs) <= hdr->frame_size) break;

		gf_bs_skip_bytes(bs, hdr->frame_size);
		val = gf_bs_read_u8(bs);
		if (val!=0xFF) {
			gf_bs_seek(bs, pos+1);
			continue;
		}
		val = gf_bs_read_int(bs, 4);
		if (val!=0x0F) {
			gf_bs_read_int(bs, 4);
			gf_bs_seek(bs, pos+1);
			continue;
		}
		gf_bs_seek(bs, pos+hdr->hdr_size);
		return 1;
	}
	gf_bs_seek(bs, start_pos);
	return 0;
}
示例#4
0
/*special authoring functions*/
GF_EXPORT
GF_BIFSConfig *gf_odf_get_bifs_config(GF_DefaultDescriptor *dsi, u8 oti)
{
	Bool hasSize, cmd_stream;
	GF_BitStream *bs;
	GF_BIFSConfig *cfg;

	if (oti>=GPAC_OTI_SCENE_BIFS_EXTENDED) return NULL;

	if (!dsi || !dsi->data || !dsi->dataLength ) {
		/* Hack for T-DMB non compliant streams (OnTimeTek ?) */
		cfg = (GF_BIFSConfig *) gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG);	
		cfg->pixelMetrics = 1;
		cfg->version = 1;
		return cfg;
	}
	bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ);
	
	cfg = (GF_BIFSConfig *) gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG);	
	if (oti==2) {
		/*3D Mesh Coding*/
		gf_bs_read_int(bs, 1);
		/*PMF*/
		gf_bs_read_int(bs, 1);
	}
	cfg->nodeIDbits = gf_bs_read_int(bs, 5);
	cfg->routeIDbits = gf_bs_read_int(bs, 5);
	if (oti==2) cfg->protoIDbits = gf_bs_read_int(bs, 5);
	
	cmd_stream = gf_bs_read_int(bs, 1);
	if (!cmd_stream) {
		cfg->elementaryMasks = gf_list_new();
		while (1) {
			GF_ElementaryMask* em = (GF_ElementaryMask* ) gf_odf_New_ElemMask();
			em->node_id = gf_bs_read_int(bs, cfg->nodeIDbits);
			gf_list_add(cfg->elementaryMasks, em);
			/*this assumes only FDP, BDP and IFS2D (no elem mask)*/
			if (gf_bs_read_int(bs, 1) == 0) break;
		}
		gf_bs_align(bs);
		if (gf_bs_get_size(bs) != gf_bs_get_position(bs)) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[ODF] Reading bifs config: shift in sizes (not supported)\n"));
		}
	} else {
		cfg->pixelMetrics = gf_bs_read_int(bs, 1);
		hasSize = gf_bs_read_int(bs, 1);
		if (hasSize) {
			cfg->pixelWidth = gf_bs_read_int(bs, 16);
			cfg->pixelHeight = gf_bs_read_int(bs, 16);
		}
		gf_bs_align(bs);
		if (gf_bs_get_size(bs) != gf_bs_get_position(bs))
			GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[ODF] Reading bifs config: shift in sizes (invalid descriptor)\n"));
	}
	gf_bs_del(bs);
	return cfg;
}
示例#5
0
文件: avc_ext.c 项目: wipple/gpac
GF_Err hvcc_Read(GF_Box *s, GF_BitStream *bs)
{
	u64 pos;
	GF_HEVCConfigurationBox *ptr = (GF_HEVCConfigurationBox *)s;

	if (ptr->config) gf_odf_hevc_cfg_del(ptr->config);

	pos = gf_bs_get_position(bs);
	ptr->config = gf_odf_hevc_cfg_read_bs(bs);
	pos = gf_bs_get_position(bs) - pos ;
	if (pos < ptr->size)
		ptr->size -= (u32) pos;

	return GF_OK;
}
示例#6
0
GF_Err store_senc_info(GF_SampleEncryptionBox *ptr, GF_BitStream *bs)
{
	GF_Err e;
	u64 pos, new_pos;
	if (!ptr->cenc_saio) return GF_OK;

	pos = gf_bs_get_position(bs);
	if (pos>0xFFFFFFFFULL) {
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] \"senc\" offset larger than 32-bits , \"saio\" box version must be 1 .\n"));
	}
	e = gf_bs_seek(bs, ptr->cenc_saio->offset_first_offset_field);
	if (e) return e;
	//force using version 1 for saio box i.e offset has 64 bits
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
	if (ptr->traf) {
		new_pos = pos - ptr->traf->moof_start_in_bs;
	} else
#endif
	{
		new_pos = pos;
	}

	if (ptr->cenc_saio->offsets_large) {
		u32 i;
		u64 old_offset = ptr->cenc_saio->offsets_large[0];
		for (i=0; i<ptr->cenc_saio->entry_count; i++) {
			gf_bs_write_u64(bs, new_pos + ptr->cenc_saio->offsets_large[i] - old_offset);
			ptr->cenc_saio->offsets_large[i] = new_pos + ptr->cenc_saio->offsets_large[i] - old_offset;
		}
	} else {
		gf_bs_write_u64(bs, new_pos);
	}

	return gf_bs_seek(bs, pos);
}
示例#7
0
GF_Err FDM_AddData(GF_FileDataMap *ptr, char *data, u32 dataSize)
{
	u32 ret;
	u64 orig;
	if (ptr->mode == GF_ISOM_DATA_MAP_READ) return GF_BAD_PARAM;

	orig = gf_bs_get_size(ptr->bs);

	/*last access was read, seek to end of file*/
	if (ptr->last_acces_was_read) {
		gf_bs_seek(ptr->bs, orig);
		ptr->last_acces_was_read = 0;
	}
	//OK, write our stuff to the datamap...
	//we don't use bs here cause we want to know more about what has been written
	ret = gf_bs_write_data(ptr->bs, data, dataSize);
	if (ret != dataSize) {
		ptr->curPos = orig;
		gf_bs_seek(ptr->bs, orig);
		return GF_IO_ERR;
	}
	ptr->curPos = gf_bs_get_position(ptr->bs);
	//flush the stream !!
	if (ptr->stream) fflush(ptr->stream);
	return GF_OK;
}
示例#8
0
GF_Err piff_psec_Read(GF_Box *s, GF_BitStream *bs)
{
	//u32 sample_count;
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
	if (ptr->size<4) return GF_ISOM_INVALID_FILE;
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);
	ISOM_DECREASE_SIZE(ptr, 4);

	if (ptr->flags & 1) {
		ptr->AlgorithmID = gf_bs_read_int(bs, 24);
		ptr->IV_size = gf_bs_read_u8(bs);
		gf_bs_read_data(bs, (char *) ptr->KID, 16);
		ISOM_DECREASE_SIZE(ptr, 20);
	}
	if (ptr->IV_size == 0)
		ptr->IV_size = 8; //default to 8

	ptr->bs_offset = gf_bs_get_position(bs);

	/*sample_count = */gf_bs_read_u32(bs);
	ISOM_DECREASE_SIZE(ptr, 4);
	if (ptr->IV_size != 8 && ptr->IV_size != 16) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] PIFF PSEC box incorrect IV size: %u - shall be 8 or 16\n", ptr->IV_size));
		return GF_BAD_PARAM;
	}
	//as for senc, we skip parsing of the box until we have all saiz/saio info
	ptr->size = 0;
	return GF_OK;
}
示例#9
0
static GF_Err gf_isom_cenc_get_sai_by_saiz_saio(GF_MediaBox *mdia, u32 sampleNumber, u8 IV_size, GF_CENCSampleAuxInfo **sai)
{
	GF_BitStream *bs;
	u32  prev_sai_size, size, i, j, nb_saio;
	u64 cur_position, offset;
	GF_Err e = GF_OK;
	char *buffer;

	nb_saio = size = prev_sai_size = 0;
	offset = 0;

	for (i = 0; i < gf_list_count(mdia->information->sampleTable->sai_offsets); i++) {
		GF_SampleAuxiliaryInfoOffsetBox *saio = (GF_SampleAuxiliaryInfoOffsetBox *)gf_list_get(mdia->information->sampleTable->sai_offsets, i);
		if (saio->aux_info_type == GF_4CC('c', 'e', 'n', 'c')) {
			if (saio->entry_count == 1)
				offset = saio->version ? saio->offsets_large[0] : saio->offsets[0];
			else
				offset = saio->version ? saio->offsets_large[sampleNumber-1]: saio->offsets[sampleNumber-1];
			nb_saio = saio->entry_count;
			break;
		}
	}

	for (i = 0; i < gf_list_count(mdia->information->sampleTable->sai_sizes); i++) {
		GF_SampleAuxiliaryInfoSizeBox *saiz = (GF_SampleAuxiliaryInfoSizeBox *)gf_list_get(mdia->information->sampleTable->sai_sizes, i);
		if (saiz->aux_info_type == GF_4CC('c', 'e', 'n', 'c')) {
			for (j = 0; j < sampleNumber-1; j++)
				prev_sai_size += saiz->default_sample_info_size ? saiz->default_sample_info_size : saiz->sample_info_size[j];
			size = saiz->default_sample_info_size ? saiz->default_sample_info_size : saiz->sample_info_size[sampleNumber-1];
			break;
		}
	}

	offset += (nb_saio == 1) ? prev_sai_size : 0;
	cur_position = gf_bs_get_position(mdia->information->dataHandler->bs);
	gf_bs_seek(mdia->information->dataHandler->bs, offset);
	buffer = (char *)gf_malloc(size);
	gf_bs_read_data(mdia->information->dataHandler->bs, buffer, size);
	gf_bs_seek(mdia->information->dataHandler->bs, cur_position);

	*sai = (GF_CENCSampleAuxInfo *)gf_malloc(sizeof(GF_CENCSampleAuxInfo));
	memset(*sai, 0, sizeof(GF_CENCSampleAuxInfo));
	bs = gf_bs_new(buffer, size, GF_BITSTREAM_READ);
	gf_bs_read_data(bs, (char *)(*sai)->IV, IV_size);
	if (size > IV_size) {
		(*sai)->subsample_count = gf_bs_read_u16(bs);
		(*sai)->subsamples = (GF_CENCSubSampleEntry *)gf_malloc(sizeof(GF_CENCSubSampleEntry)*(*sai)->subsample_count);
		for (i = 0; i < (*sai)->subsample_count; i++) {
			(*sai)->subsamples[i].bytes_clear_data = gf_bs_read_u16(bs);
			(*sai)->subsamples[i].bytes_encrypted_data = gf_bs_read_u32(bs);
		}
	}
	gf_bs_del(bs);

	return e;
}
示例#10
0
GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, void *traf, GF_SampleEncryptionBox *senc)
#endif
{
	GF_Err e;
	u32 i, j, count;
	u64 pos = gf_bs_get_position(bs);

#ifdef	GPAC_DISABLE_ISOM_FRAGMENTS
	if (!traf)
		return GF_BAD_PARAM;
#endif

	gf_bs_seek(bs, senc->bs_offset);

	count = gf_bs_read_u32(bs);
	if (!senc->samp_aux_info) senc->samp_aux_info = gf_list_new();
	for (i=0; i<count; i++) {
		u32 is_encrypted;
		u32 samp_count;
		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_malloc(sizeof(GF_CENCSampleAuxInfo));
		memset(sai, 0, sizeof(GF_CENCSampleAuxInfo));

		samp_count = i+1;
#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
		if (trak) samp_count += trak->sample_count_at_seg_start;
#endif

		if (trak) {
			e = gf_isom_get_sample_cenc_info_ex(trak, traf, senc, samp_count, &is_encrypted, &sai->IV_size, NULL, NULL, NULL, NULL, NULL);
			if (e) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] could not get cenc info for sample %d: %s\n", samp_count, gf_error_to_string(e) ));
				return e;
			}
		}
		//no init movie setup (segment dump/inspaction, assume default encrypted and 16 bytes IV
		else {
			is_encrypted = GF_TRUE;
			sai->IV_size = 16;
		}

		if (is_encrypted) {
			gf_bs_read_data(bs, (char *)sai->IV, sai->IV_size);
			if (senc->flags & 0x00000002) {
				sai->subsample_count = gf_bs_read_u16(bs);
				sai->subsamples = (GF_CENCSubSampleEntry *)gf_malloc(sai->subsample_count*sizeof(GF_CENCSubSampleEntry));
				for (j = 0; j < sai->subsample_count; j++) {
					sai->subsamples[j].bytes_clear_data = gf_bs_read_u16(bs);
					sai->subsamples[j].bytes_encrypted_data = gf_bs_read_u32(bs);
				}
			}
		}
		gf_list_add(senc->samp_aux_info, sai);
	}
	gf_bs_seek(bs, pos);
	return GF_OK;
}
示例#11
0
文件: bifs_codec.c 项目: erelh/gpac
static GF_Err ParseConfig(GF_BitStream *bs, BIFSStreamInfo *info, u32 version)
{
	Bool hasSize, cmd_stream;

	if (info->config.elementaryMasks) gf_list_del(info->config.elementaryMasks);
	info->config.elementaryMasks = NULL	;

	if (version==2) {
		info->config.Use3DMeshCoding = gf_bs_read_int(bs, 1);
		info->config.UsePredictiveMFField = gf_bs_read_int(bs, 1);
	}
	info->config.NodeIDBits = gf_bs_read_int(bs, 5);
	info->config.RouteIDBits = gf_bs_read_int(bs, 5);
	if (version==2) {
		info->config.ProtoIDBits = gf_bs_read_int(bs, 5);
	}
	cmd_stream = gf_bs_read_int(bs, 1);

	if (cmd_stream) {
		info->config.PixelMetrics = gf_bs_read_int(bs, 1);
		hasSize = gf_bs_read_int(bs, 1);
		if (hasSize) {
			info->config.Width = gf_bs_read_int(bs, 16);
			info->config.Height = gf_bs_read_int(bs, 16);
		}
		gf_bs_align(bs);

		if (gf_bs_get_size(bs) != gf_bs_get_position(bs)) return GF_ODF_INVALID_DESCRIPTOR;
		return GF_OK;
	} else {
		info->config.BAnimRAP = gf_bs_read_int(bs, 1);
		info->config.elementaryMasks = gf_list_new();
		while (1) {
		  /*u32 node_id = */gf_bs_read_int(bs, info->config.NodeIDBits);
			/*this assumes only FDP, BDP and IFS2D (no elem mask)*/
			if (gf_bs_read_int(bs, 1) == 0) break;
		}
		gf_bs_align(bs);
		if (gf_bs_get_size(bs) != gf_bs_get_position(bs))  return GF_NOT_SUPPORTED;
		return GF_OK;
	}
}
示例#12
0
GF_Err senc_Read(GF_Box *s, GF_BitStream *bs)
{
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);
	ISOM_DECREASE_SIZE(ptr, 4);

	ptr->bs_offset = gf_bs_get_position(bs);
	gf_bs_skip_bytes(bs, ptr->size);
	ptr->size = 0;
	return GF_OK;
}
示例#13
0
GF_Err meta_Read(GF_Box *s, GF_BitStream *bs)
{
	u64 pos = gf_bs_get_position(bs);
	u64 size = s->size;
	GF_Err e = gf_isom_box_array_read(s, bs, meta_AddBox);
	/*try to hack around QT files which don't use a full box for meta, rewind 4 bytes*/
	if (e && (pos>4) ) {
		gf_bs_seek(bs, pos-4);
		meta_reset(s);
		s->size = size+4;
		e = gf_isom_box_array_read(s, bs, meta_AddBox);
	}
	return e;
}
示例#14
0
GF_EXPORT
void gf_sl_depacketize (GF_SLConfig *slConfig, GF_SLHeader *Header, char *PDU, u32 PDULength, u32 *HeaderLen)
{
	GF_BitStream *bs;
	*HeaderLen = 0;
	if (!Header) return;
	//reset the input header
	memset(Header, 0, sizeof(GF_SLHeader));

	bs = gf_bs_new(PDU, PDULength, GF_BITSTREAM_READ);
	if (!bs) return;

	if (slConfig->useAccessUnitStartFlag) Header->accessUnitStartFlag = gf_bs_read_int(bs, 1);
	if (slConfig->useAccessUnitEndFlag) Header->accessUnitEndFlag = gf_bs_read_int(bs, 1);
	if ( !slConfig->useAccessUnitStartFlag && !slConfig->useAccessUnitEndFlag) {
		Header->accessUnitStartFlag = 1;
		Header->accessUnitEndFlag = 1;
	}
	if (slConfig->OCRLength > 0) Header->OCRflag = gf_bs_read_int(bs, 1);
	if (slConfig->useIdleFlag) Header->idleFlag = gf_bs_read_int(bs, 1);
	if (slConfig->usePaddingFlag) {
		Header->paddingFlag = gf_bs_read_int(bs, 1);
		if (Header->paddingFlag) Header->paddingBits = gf_bs_read_int(bs, 3);
	}
	if (!Header->idleFlag && (!Header->paddingFlag || Header->paddingBits != 0)) {

		if (slConfig->packetSeqNumLength > 0) Header->packetSequenceNumber = gf_bs_read_int(bs, slConfig->packetSeqNumLength);
		if (slConfig->degradationPriorityLength > 0) {
			Header->degradationPriorityFlag = gf_bs_read_int(bs, 1);
			if (Header->degradationPriorityFlag) Header->degradationPriority = gf_bs_read_int(bs, slConfig->degradationPriorityLength);
		}
		if (Header->OCRflag) Header->objectClockReference = gf_bs_read_int(bs, slConfig->OCRLength);
		if (Header->accessUnitStartFlag) {
			if (slConfig->useRandomAccessPointFlag) Header->randomAccessPointFlag = gf_bs_read_int(bs, 1);
			if (slConfig->AUSeqNumLength > 0) Header->AU_sequenceNumber = gf_bs_read_int(bs, slConfig->AUSeqNumLength);
			if (slConfig->useTimestampsFlag) {
				Header->decodingTimeStampFlag = gf_bs_read_int(bs, 1);
				Header->compositionTimeStampFlag = gf_bs_read_int(bs, 1);
			}
			if (slConfig->instantBitrateLength > 0) Header->instantBitrateFlag = gf_bs_read_int(bs, 1);
			if (Header->decodingTimeStampFlag) Header->decodingTimeStamp = gf_bs_read_long_int(bs, slConfig->timestampLength); 
			if (Header->compositionTimeStampFlag) Header->compositionTimeStamp = gf_bs_read_long_int(bs, slConfig->timestampLength); 
			if (slConfig->AULength > 0) Header->accessUnitLength = gf_bs_read_int(bs, slConfig->AULength);
			if (Header->instantBitrateFlag) Header->instantBitrate = gf_bs_read_int(bs, slConfig->instantBitrateLength);
		}
	}
	gf_bs_align(bs);
	*HeaderLen = (u32) gf_bs_get_position(bs);
	gf_bs_del(bs);
}
示例#15
0
GF_Err piff_psec_Read(GF_Box *s, GF_BitStream *bs)
{
	u32 sample_count, i, j;
	GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *)s;
	if (ptr->size<4) return GF_ISOM_INVALID_FILE;
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);
	ptr->size -= 4;

	if (ptr->flags & 1) {
		ptr->AlgorithmID = gf_bs_read_int(bs, 24);
		ptr->IV_size = gf_bs_read_u8(bs);
		gf_bs_read_data(bs, (char *)ptr->KID, 16);
		ptr->size -= 20;
	}
	if (ptr->IV_size == 0)
		ptr->IV_size = 8; //default to 8

	sample_count = gf_bs_read_u32(bs);
	ptr->size -= 4;
	if (ptr->IV_size != 8 && ptr->IV_size != 16) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] PIFF PSEC box incorrect IV size: %u - shall be 8 or 16\n", ptr->IV_size));
		return GF_BAD_PARAM;
	}

	ptr->samp_aux_info = gf_list_new();
	for (i = 0; i<sample_count; ++i) {
		GF_CENCSampleAuxInfo *sai;
		GF_SAFEALLOC(sai, GF_CENCSampleAuxInfo);
		if (!sai) return GF_OUT_OF_MEM;

		sai->IV_size = ptr->IV_size;
		gf_bs_read_data(bs, (char *)sai->IV, ptr->IV_size);
		ptr->size -= ptr->IV_size;
		if (ptr->flags & 2) {
			sai->subsample_count = gf_bs_read_u16(bs);
			sai->subsamples = gf_malloc(sai->subsample_count * sizeof(GF_CENCSubSampleEntry));
			for (j = 0; j < sai->subsample_count; ++j) {
				sai->subsamples[j].bytes_clear_data = gf_bs_read_u16(bs);
				sai->subsamples[j].bytes_encrypted_data = gf_bs_read_u32(bs);
			}
			ptr->size -= 2 + sai->subsample_count * 6;
		}
		gf_list_add(ptr->samp_aux_info, sai);
	}

	ptr->bs_offset = gf_bs_get_position(bs);
	assert(ptr->size == 0);
	return GF_OK;
}
示例#16
0
GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, void *traf, GF_SampleEncryptionBox *ptr)
#endif
{
	GF_Err e;
	u32 i, j, count;
	u64 pos = gf_bs_get_position(bs);

#ifdef	GPAC_DISABLE_ISOM_FRAGMENTS
	if (!traf)
		return GF_BAD_PARAM;
#endif

	gf_bs_seek(bs, ptr->bs_offset);

	count = gf_bs_read_u32(bs);
	if (!ptr->samp_aux_info) ptr->samp_aux_info = gf_list_new();
	for (i=0; i<count; i++) {
		u32 is_encrypted;
		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_malloc(sizeof(GF_CENCSampleAuxInfo));
		memset(sai, 0, sizeof(GF_CENCSampleAuxInfo));

		e = gf_isom_get_sample_cenc_info_ex(trak, traf, (trak ? trak->sample_count_at_seg_start : 0 )+ i+1, &is_encrypted, &sai->IV_size, NULL);
		if (e) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] could not get cenc info for sample %d: %s\n", trak->sample_count_at_seg_start + i+1, gf_error_to_string(e) ));
			return e;
		}
		if (is_encrypted) {
			gf_bs_read_data(bs, (char *)sai->IV, sai->IV_size);
			if (ptr->flags & 0x00000002) {
				sai->subsample_count = gf_bs_read_u16(bs);
				sai->subsamples = (GF_CENCSubSampleEntry *)gf_malloc(sai->subsample_count*sizeof(GF_CENCSubSampleEntry));
				for (j = 0; j < sai->subsample_count; j++) {
					sai->subsamples[j].bytes_clear_data = gf_bs_read_u16(bs);
					sai->subsamples[j].bytes_encrypted_data = gf_bs_read_u32(bs);
				}
			}
		}
		gf_list_add(ptr->samp_aux_info, sai);
	}
	gf_bs_seek(bs, pos);
	return GF_OK;
}
示例#17
0
GF_Err store_senc_info(GF_SampleEncryptionBox *ptr, GF_BitStream *bs)
{
	GF_Err e;
	u64 pos;
	if (!ptr->cenc_saio) return GF_OK;

	pos = gf_bs_get_position(bs);
	if (pos>0xFFFFFFFFULL) {
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] \"senc\" offset larger than 32-bits , \"saio\" box version must be 1 .\n"));
	}
	e = gf_bs_seek(bs, ptr->cenc_saio->offset_first_offset_field);
	if (e) return e;
	//force using version 1 for saio box i.e offset has 64 bits
	if (ptr->traf) {
		gf_bs_write_u64(bs, pos - ptr->traf->moof_start_in_bs );
	} else {
		gf_bs_write_u64(bs, pos);
	}
	return gf_bs_seek(bs, pos);
}
示例#18
0
GF_Err piff_psec_Read(GF_Box *s, GF_BitStream *bs)
{
	GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *)s;
	if (ptr->size<4) return GF_ISOM_INVALID_FILE;
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);
	ptr->size -= 4;

	if (ptr->flags & 1) {
		ptr->AlgorithmID = gf_bs_read_int(bs, 24);
		ptr->IV_size = gf_bs_read_u8(bs);
		gf_bs_read_data(bs, (char *) ptr->KID, 16);
		ptr->size -= 20;
	}

	ptr->bs_offset = gf_bs_get_position(bs);
	gf_bs_skip_bytes(bs, ptr->size);
	ptr->size = 0;
	return GF_OK;
}
示例#19
0
GF_Err store_senc_info(GF_SampleEncryptionBox *ptr, GF_BitStream *bs)
{
	GF_Err e;
	u64 pos;
	if (!ptr->cenc_saio) return GF_OK;

	pos = gf_bs_get_position(bs);
	if (pos>0xFFFFFFFFULL) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] \"senc\" offset larger than 32-bits , cannot store.\n"));
		return GF_NOT_SUPPORTED;
	}
	e = gf_bs_seek(bs, ptr->cenc_saio->offset_first_offset_field);
	if (e) return e;
	if (ptr->traf) {
		gf_bs_write_u32(bs, (u32) ( pos - ptr->traf->moof_start_in_bs) );
	} else {
		gf_bs_write_u32(bs, (u32) pos);
	}
	return gf_bs_seek(bs, pos);
}
示例#20
0
文件: meta.c 项目: Brilon314/gpac
GF_Err gf_isom_add_meta_item_extended(GF_ISOFile *file, Bool root_meta, u32 track_num, Bool self_reference, char *resource_path,
                                      const char *item_name, u32 item_id, const char *mime_type, const char *content_encoding,
                                      GF_ImageItemProperties *image_props,
                                      const char *URL, const char *URN,
                                      char *data, u32 data_len)
{
	GF_Err e;
	GF_ItemLocationEntry *location_entry;
	GF_ItemInfoEntryBox *infe;
	GF_MetaBox *meta;
	u32 lastItemID = 0;

	if (!self_reference && !item_name && !resource_path) return GF_BAD_PARAM;
	e = CanAccessMovie(file, GF_ISOM_OPEN_WRITE);
	if (e) return e;
	meta = gf_isom_get_meta(file, root_meta, track_num);
	if (!meta) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Trying to add item, but missing meta box"));
		return GF_BAD_PARAM;
	}

	e = FlushCaptureMode(file);
	if (e) return e;

	/*check file exists */
	if (!URN && !URL && !self_reference && !data) {
		FILE *src = gf_fopen(resource_path, "rb");
		if (!src) return GF_URL_ERROR;
		gf_fclose(src);
	}

	if (meta->item_infos) {
		u32 i;
		u32 item_count = gf_list_count(meta->item_infos->item_infos);
		for (i = 0; i < item_count; i++) {
			GF_ItemInfoEntryBox *e= (GF_ItemInfoEntryBox *)gf_list_get(meta->item_infos->item_infos, i);
			if (e->item_ID > lastItemID) lastItemID = e->item_ID;
			if (item_id == e->item_ID) {
				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[IsoMedia] Item with id %d already exists, ignoring\n", item_id));
				item_id = 0;
			}
		}
	}

	infe = (GF_ItemInfoEntryBox *)infe_New();
	if (item_id) {
		infe->item_ID = item_id;
	} else {
		infe->item_ID = ++lastItemID;
	}

	/*get relative name*/
	if (item_name) {
		infe->item_name = gf_strdup(item_name);
	} else if (resource_path) {
		if (strrchr(resource_path, GF_PATH_SEPARATOR)) {
			infe->item_name = gf_strdup(strrchr(resource_path, GF_PATH_SEPARATOR) + 1);
		} else {
			infe->item_name = gf_strdup(resource_path);
		}
	}

	if (mime_type) {
		infe->content_type = gf_strdup(mime_type);
	} else {
		infe->content_type = gf_strdup("application/octet-stream");
	}
	if (content_encoding) infe->content_encoding = gf_strdup(content_encoding);

	/*Creation of the ItemLocation */
	location_entry = (GF_ItemLocationEntry*)gf_malloc(sizeof(GF_ItemLocationEntry));
	if (!location_entry) {
		gf_isom_box_del((GF_Box *)infe);
		return GF_OUT_OF_MEM;
	}
	memset(location_entry, 0, sizeof(GF_ItemLocationEntry));
	location_entry->extent_entries = gf_list_new();

	/*Creates an mdat if it does not exist*/
	if (!file->mdat) {
		file->mdat = (GF_MediaDataBox *)mdat_New();
		gf_list_add(file->TopBoxes, file->mdat);
	}

	/*Creation an ItemLocation Box if it does not exist*/
	if (!meta->item_locations) meta->item_locations = (GF_ItemLocationBox *)iloc_New();
	gf_list_add(meta->item_locations->location_entries, location_entry);
	location_entry->item_ID = infe->item_ID;

	if (!meta->item_infos) meta->item_infos = (GF_ItemInfoBox *) iinf_New();
	e = gf_list_add(meta->item_infos->item_infos, infe);
	if (e) return e;

	if (image_props) {
		meta_process_image_properties(meta, infe->item_ID, image_props);
	}

	/*0: the current file*/
	location_entry->data_reference_index = 0;
	if (self_reference) {
		GF_ItemExtentEntry *entry;
		GF_SAFEALLOC(entry, GF_ItemExtentEntry);
		gf_list_add(location_entry->extent_entries, entry);
		if (!infe->item_name) infe->item_name = gf_strdup("");
		return GF_OK;
	}

	/*file not copied, just referenced*/
	if (URL || URN) {
		u32 dataRefIndex;
		if (!meta->file_locations) meta->file_locations = (GF_DataInformationBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DINF);
		if (!meta->file_locations->dref) meta->file_locations->dref = (GF_DataReferenceBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DREF);
		e = Media_FindDataRef(meta->file_locations->dref, (char *) URL, (char *) URN, &dataRefIndex);
		if (e) return e;
		if (!dataRefIndex) {
			e = Media_CreateDataRef(meta->file_locations->dref, (char *) URL, (char *) URN, &dataRefIndex);
			if (e) return e;
		}
		location_entry->data_reference_index = dataRefIndex;
	}

	/*capture mode, write to disk*/
	if ((file->openMode == GF_ISOM_OPEN_WRITE) && !location_entry->data_reference_index) {
		FILE *src;
		GF_ItemExtentEntry *entry;
		GF_SAFEALLOC(entry, GF_ItemExtentEntry);

		location_entry->base_offset = gf_bs_get_position(file->editFileMap->bs);

		/*update base offset size*/
		if (location_entry->base_offset>0xFFFFFFFF) meta->item_locations->base_offset_size = 8;
		else if (location_entry->base_offset && !meta->item_locations->base_offset_size) meta->item_locations->base_offset_size = 4;

		entry->extent_length = 0;
		entry->extent_offset = 0;
		gf_list_add(location_entry->extent_entries, entry);

		if (data) {
			gf_bs_write_data(file->editFileMap->bs, data, data_len);
			/*update length size*/
			if (entry->extent_length>0xFFFFFFFF) meta->item_locations->length_size = 8;
			else if (entry->extent_length && !meta->item_locations->length_size) meta->item_locations->length_size = 4;
		} else if (resource_path) {
			src = gf_fopen(resource_path, "rb");
			if (src) {
				char cache_data[4096];
				u64 remain;
				gf_fseek(src, 0, SEEK_END);
				entry->extent_length = gf_ftell(src);
				gf_fseek(src, 0, SEEK_SET);

				remain = entry->extent_length;
				while (remain) {
					u32 size_cache = (remain>4096) ? 4096 : (u32) remain;
					size_t read = fread(cache_data, 1, size_cache, src);
					if (read==(size_t)-1) break;
					gf_bs_write_data(file->editFileMap->bs, cache_data, (u32) read);
					remain -= (u32) read;
				}
				gf_fclose(src);

				/*update length size*/
				if (entry->extent_length>0xFFFFFFFF) meta->item_locations->length_size = 8;
				else if (entry->extent_length && !meta->item_locations->length_size) meta->item_locations->length_size = 4;
			}
		}
	}
	/*store full path for info*/
	else if (!location_entry->data_reference_index) {
		if (data) {
			infe->full_path = (char *)gf_malloc(sizeof(char) * data_len);
			memcpy(infe->full_path, data, sizeof(char) * data_len);
			infe->data_len = data_len;
		} else {
			infe->full_path = gf_strdup(resource_path);
			infe->data_len = 0;
		}
	}
	return GF_OK;
}
示例#21
0
static GF_Err SVG_ProcessData(GF_SceneDecoder *plug, const char *inBuffer, u32 inBufferLength,
                              u16 ES_ID, u32 stream_time, u32 mmlevel)
{
	GF_Err e = GF_OK;
	SVGIn *svgin = (SVGIn *)plug->privateStack;

	if (stream_time==(u32)-1) {
		if (svgin->src) gzclose(svgin->src);
		svgin->src = NULL;
		gf_sm_load_done(&svgin->loader);
		svgin->loader.fileName = NULL;
		svgin->file_pos = 0;
		gf_sg_reset(svgin->scene->graph);
		return GF_OK;
	}

	switch (svgin->oti) {
	/*!OTI for SVG dummy stream (dsi = file name) - GPAC internal*/
	case GPAC_OTI_PRIVATE_SCENE_SVG:
		/*full doc parsing*/
		if ((svgin->sax_max_duration==(u32) -1) && svgin->file_size) {
			/*init step*/
			if (!svgin->loader.fileName) {
				/*not done yet*/
				if (!svg_check_download(svgin)) return GF_OK;
				svgin->loader.fileName = svgin->file_name;
				e = gf_sm_load_init(&svgin->loader);
			} else {
				e = gf_sm_load_run(&svgin->loader);
			}
		}
		/*chunk parsing*/
		else {
			u32 entry_time;
			char file_buf[SVG_PROGRESSIVE_BUFFER_SIZE+2];
			/*initial load*/
			if (!svgin->src && !svgin->file_pos) {
				svgin->src = gzopen(svgin->file_name, "rb");
				if (!svgin->src) return GF_URL_ERROR;
				svgin->loader.fileName = svgin->file_name;
				gf_sm_load_init(&svgin->loader);
			}
			e = GF_OK;
			entry_time = gf_sys_clock();

			while (1) {
				u32 diff;
				s32 nb_read;
				nb_read = gzread(svgin->src, file_buf, SVG_PROGRESSIVE_BUFFER_SIZE);
				/*we may have read nothing but we still need to call parse in case the parser got suspended*/
				if (nb_read<=0) {
					nb_read = 0;
					if ((e==GF_EOS) && gzeof(svgin->src)) {
						gf_set_progress("SVG Parsing", svgin->file_pos, svgin->file_size);
						gzclose(svgin->src);
						svgin->src = NULL;
						gf_sm_load_done(&svgin->loader);
					}
					goto exit;
				}

				file_buf[nb_read] = file_buf[nb_read+1] = 0;

				e = gf_sm_load_string(&svgin->loader, file_buf, 0);
				svgin->file_pos += nb_read;



				/*handle decompression*/
				if (svgin->file_pos > svgin->file_size) svgin->file_size = svgin->file_pos + 1;
				if (e) break;

				gf_set_progress("SVG Parsing", svgin->file_pos, svgin->file_size);
				diff = gf_sys_clock() - entry_time;
				if (diff > svgin->sax_max_duration) {
					break;
				}
			}
		}
		break;

	/*!OTI for streaming SVG - GPAC internal*/
	case GPAC_OTI_SCENE_SVG:
		e = gf_sm_load_string(&svgin->loader, inBuffer, 0);
		break;

	/*!OTI for streaming SVG + gz - GPAC internal*/
	case GPAC_OTI_SCENE_SVG_GZ:
		e = svgin_deflate(svgin, inBuffer, inBufferLength);
		break;

	/*!OTI for DIMS (dsi = 3GPP DIMS configuration) - GPAC internal*/
	case GPAC_OTI_SCENE_DIMS:
	{
		u8 prev, dims_hdr;
		u32 nb_bytes, size;
		u64 pos;
		char * buf2 = gf_malloc(inBufferLength);
		GF_BitStream *bs = gf_bs_new(inBuffer, inBufferLength, GF_BITSTREAM_READ);
		memcpy(buf2, inBuffer, inBufferLength);
//			FILE *f = gf_f64_open("dump.svg", "wb");
//
		while (gf_bs_available(bs)) {
			pos = gf_bs_get_position(bs);
			size = gf_bs_read_u16(bs);
			nb_bytes = 2;
			/*GPAC internal hack*/
			if (!size) {
				size = gf_bs_read_u32(bs);
				nb_bytes = 6;
			}
//	            gf_fwrite( inBuffer + pos + nb_bytes + 1, 1, size - 1, f );

			dims_hdr = gf_bs_read_u8(bs);
			prev = buf2[pos + nb_bytes + size];

			buf2[pos + nb_bytes + size] = 0;
			if (dims_hdr & GF_DIMS_UNIT_C) {
				e = svgin_deflate(svgin, buf2 + pos + nb_bytes + 1, size - 1);
			} else {
				e = gf_sm_load_string(&svgin->loader, buf2 + pos + nb_bytes + 1, 0);
			}
			buf2[pos + nb_bytes + size] = prev;
			gf_bs_skip_bytes(bs, size-1);

		}
//          fclose(f);
		gf_bs_del(bs);
	}
	break;

	default:
		return GF_BAD_PARAM;
	}

exit:
	if ((e>=GF_OK) && (svgin->scene->graph_attached!=1) && (gf_sg_get_root_node(svgin->loader.scene_graph)!=NULL) ) {
		gf_scene_attach_to_compositor(svgin->scene);
	}
	/*prepare for next playback*/
	if (e) {
		gf_sm_load_done(&svgin->loader);
		svgin->loader.fileName = NULL;
		e = GF_EOS;
	}
	return e;
}
示例#22
0
//write the file track by track, with moov box before or after the mdat
GF_Err WriteFlat(MovieWriter *mw, u8 moovFirst, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	u64 offset, finalOffset, totSize, begin, firstSize, finalSize;
	GF_Box *a;
	GF_List *writers = gf_list_new();
	GF_ISOFile *movie = mw->movie;

	begin = totSize = 0;

	//first setup the writers
	e = SetupWriters(mw, writers, 0);
	if (e) goto exit;

	if (!moovFirst) {
		if (movie->openMode == GF_ISOM_OPEN_WRITE) {
			begin = 0;
			totSize = gf_isom_datamap_get_offset(movie->editFileMap);
			/*start boxes have not been written yet, do it*/
			if (!totSize) {
				if (movie->is_jp2) {
					gf_bs_write_u32(movie->editFileMap->bs, 12);
					gf_bs_write_u32(movie->editFileMap->bs, GF_4CC('j','P',' ',' '));
					gf_bs_write_u32(movie->editFileMap->bs, 0x0D0A870A);
					totSize += 12;
					begin += 12;
				}
				if (movie->brand) {
					e = gf_isom_box_size((GF_Box *)movie->brand); if (e) goto exit;
					e = gf_isom_box_write((GF_Box *)movie->brand, movie->editFileMap->bs); if (e) goto exit;
					totSize += movie->brand->size;
					begin += movie->brand->size;
				}
				if (movie->pdin) {
					e = gf_isom_box_size((GF_Box *)movie->pdin); if (e) goto exit;
					e = gf_isom_box_write((GF_Box *)movie->pdin, movie->editFileMap->bs); if (e) goto exit;
					totSize += movie->pdin->size;
					begin += movie->pdin->size;
				}
			} else {
				if (movie->is_jp2) begin += 12;
				if (movie->brand) begin += movie->brand->size;
				if (movie->pdin) begin += movie->pdin->size;
			}
			totSize -= begin;
		} else {
			if (movie->is_jp2) {
				gf_bs_write_u32(bs, 12);
				gf_bs_write_u32(bs, GF_4CC('j','P',' ',' '));
				gf_bs_write_u32(bs, 0x0D0A870A);
			}
			if (movie->brand) {
				e = gf_isom_box_size((GF_Box *)movie->brand);
				if (e) goto exit;
				e = gf_isom_box_write((GF_Box *)movie->brand, bs);
				if (e) goto exit;
			}
			/*then progressive download*/
			if (movie->pdin) {
				e = gf_isom_box_size((GF_Box *)movie->pdin);
				if (e) goto exit;
				e = gf_isom_box_write((GF_Box *)movie->pdin, bs);
				if (e) goto exit;
			}
		}

		//if the moov is at the end, write directly
		i=0;
		while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) {
			switch (a->type) {
			/*written by hand*/
			case GF_ISOM_BOX_TYPE_MOOV:
			case GF_ISOM_BOX_TYPE_META:
			case GF_ISOM_BOX_TYPE_FTYP:
			case GF_ISOM_BOX_TYPE_PDIN:
				break;
			case GF_ISOM_BOX_TYPE_MDAT:
				//in case we're capturing
				if (movie->openMode == GF_ISOM_OPEN_WRITE) {
					//emulate a write to recreate our tables (media data already written)
					e = DoWrite(mw, writers, bs, 1, begin);
					if (e) goto exit;
					continue;
				}
				//to avoid computing the size each time write always 4 + 4 + 8 bytes before
				begin = gf_bs_get_position(bs);
				gf_bs_write_u64(bs, 0);
				gf_bs_write_u64(bs, 0);
				e = DoWrite(mw, writers, bs, 0, gf_bs_get_position(bs));
				if (e) goto exit;
				totSize = gf_bs_get_position(bs) - begin;
				break;
			default:
				e = gf_isom_box_size(a);
				if (e) goto exit;
				e = gf_isom_box_write(a, bs);
				if (e) goto exit;
				break;
			}
		}

		//OK, write the movie box.
		e = WriteMoovAndMeta(movie, writers, bs);
		if (e) goto exit;

		/*if data has been written, update mdat size*/
		if (totSize) {
			offset = gf_bs_get_position(bs);
			e = gf_bs_seek(bs, begin);
			if (e) goto exit;
			if (totSize > 0xFFFFFFFF) {
				gf_bs_write_u32(bs, 1);
			} else {
				gf_bs_write_u32(bs, (u32) totSize);
			}
			gf_bs_write_u32(bs, GF_ISOM_BOX_TYPE_MDAT);
			if (totSize > 0xFFFFFFFF) gf_bs_write_u64(bs, totSize);
			e = gf_bs_seek(bs, offset);
		}
		movie->mdat->size = totSize;
		goto exit;
	}

	//nope, we have to write the moov first. The pb is that 
	//1 - we don't know its size till the mdat is written
	//2 - we don't know the ofset at which the mdat will start...
	//3 - once the mdat is written, the chunkOffset table can have changed...
	
	if (movie->is_jp2) {
		gf_bs_write_u32(bs, 12);
		gf_bs_write_u32(bs, GF_4CC('j','P',' ',' '));
		gf_bs_write_u32(bs, 0x0D0A870A);
	}
	if (movie->brand) {
		e = gf_isom_box_size((GF_Box *)movie->brand);
		if (e) goto exit;
		e = gf_isom_box_write((GF_Box *)movie->brand, bs);
		if (e) goto exit;
	}
	/*then progressive dnload*/
	if (movie->pdin) {
		e = gf_isom_box_size((GF_Box *)movie->pdin);
		if (e) goto exit;
		e = gf_isom_box_write((GF_Box *)movie->pdin, bs);
		if (e) goto exit;
	}
	//What we will do is first emulate the write from the begining...
	//note: this will set the size of the mdat
	e = DoWrite(mw, writers, bs, 1, gf_bs_get_position(bs));
	if (e) goto exit;
	
	firstSize = GetMoovAndMetaSize(movie, writers);
	//offset = (firstSize > 0xFFFFFFFF ? firstSize + 8 : firstSize) + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);
	offset = firstSize + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);
	e = ShiftOffset(movie, writers, offset);
	if (e) goto exit;
	//get the size and see if it has changed (eg, we moved to 64 bit offsets)
	finalSize = GetMoovAndMetaSize(movie, writers);
	if (firstSize != finalSize) {
		//we need to remove our offsets
		ResetWriters(writers);
		//finalOffset = (finalSize > 0xFFFFFFFF ? finalSize + 8 : finalSize) + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);
		finalOffset = finalSize + 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);
		//OK, now we're sure about the final size.
		//we don't need to re-emulate, as the only thing that changed is the offset
		//so just shift the offset
		e = ShiftOffset(movie, writers, finalOffset - offset);
		if (e) goto exit;
	}
	//now write our stuff
	e = WriteMoovAndMeta(movie, writers, bs);
	if (e) goto exit;
	e = gf_isom_box_size((GF_Box *)movie->mdat);
	if (e) goto exit;
	e = gf_isom_box_write((GF_Box *)movie->mdat, bs);
	if (e) goto exit;

	//we don't need the offset as the moov is already written...
	ResetWriters(writers);
	e = DoWrite(mw, writers, bs, 0, 0);
	if (e) goto exit;
	//then the rest
	i=0;
	while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) {
		switch (a->type) {
		case GF_ISOM_BOX_TYPE_MOOV:
		case GF_ISOM_BOX_TYPE_META:
		case GF_ISOM_BOX_TYPE_FTYP:
		case GF_ISOM_BOX_TYPE_PDIN:
		case GF_ISOM_BOX_TYPE_MDAT:
			break;
		default:
			e = gf_isom_box_size(a);
			if (e) goto exit;
			e = gf_isom_box_write(a, bs);
			if (e) goto exit;
		}
	}

exit:
	CleanWriters(writers);
	gf_list_del(writers);
	return e;
}
示例#23
0
GF_EXPORT
void gf_img_parse(GF_BitStream *bs, u8 *OTI, u32 *mtype, u32 *width, u32 *height, char **dsi, u32 *dsi_len)
{
	u8 b1, b2, b3;
	u32 size, type;
	u64 pos;
	pos = gf_bs_get_position(bs);
	gf_bs_seek(bs, 0);

	*mtype = *width = *height = 0;
	*OTI = 0;
	if (dsi) {
		*dsi = NULL;
		*dsi_len = 0;
	}

	b1 = gf_bs_read_u8(bs);
	b2 = gf_bs_read_u8(bs);
	b3 = gf_bs_read_u8(bs);
	/*JPEG*/
	if ((b1==0xFF) && (b2==0xD8) && (b3==0xFF)) {
		u32 offset = 0;
		u32 Xdens, Ydens, nb_comp;
		gf_bs_read_u8(bs);
		gf_bs_skip_bytes(bs, 10);	/*2 size, 5 JFIF\0, 2 version, 1 units*/
		Xdens = gf_bs_read_int(bs, 16);
		Ydens = gf_bs_read_int(bs, 16);
		nb_comp = 0;

		/*get frame header FFC0*/
		while (gf_bs_available(bs)) {
			u32 type, w, h;
			if (gf_bs_read_u8(bs) != 0xFF) continue;
			if (!offset) offset = (u32)gf_bs_get_position(bs) - 1;

			type = gf_bs_read_u8(bs);
			/*process all Start of Image markers*/
			switch (type) {
			case 0xC0:
			case 0xC1:
			case 0xC2:
			case 0xC3:
			case 0xC5:
			case 0xC6:
			case 0xC7:
			case 0xC9:
			case 0xCA:
			case 0xCB:
			case 0xCD:
			case 0xCE:
			case 0xCF:
				gf_bs_skip_bytes(bs, 3);
				h = gf_bs_read_int(bs, 16);
				w = gf_bs_read_int(bs, 16);
				if ((w > *width) || (h > *height)) {
					*width = w;
					*height = h;
				}
				nb_comp = gf_bs_read_int(bs, 8);
				break;
			}
		}
		*OTI = GPAC_OTI_IMAGE_JPEG;
		*mtype = GF_4CC('j','p','e','g');
		if (dsi) {
			GF_BitStream *bs_dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
			gf_bs_write_u16(bs_dsi, offset);
			gf_bs_write_u16(bs_dsi, Xdens);
			gf_bs_write_u16(bs_dsi, Ydens);
			gf_bs_write_u8(bs_dsi, nb_comp);
			gf_bs_get_content(bs_dsi, dsi, dsi_len);
			gf_bs_del(bs_dsi);
		}
	}
	/*PNG*/
	else if ((b1==0x89) && (b2==0x50) && (b3==0x4E)) {
		/*check for PNG sig*/
		if ( (gf_bs_read_u8(bs) != 0x47) || (gf_bs_read_u8(bs) != 0x0D) || (gf_bs_read_u8(bs) != 0x0A)
			|| (gf_bs_read_u8(bs) != 0x1A) || (gf_bs_read_u8(bs) != 0x0A) ) goto exit;
		gf_bs_read_u32(bs);
		/*check for PNG IHDR*/
		if ( (gf_bs_read_u8(bs) != 'I') || (gf_bs_read_u8(bs) != 'H')
			|| (gf_bs_read_u8(bs) != 'D') || (gf_bs_read_u8(bs) != 'R')) goto exit;

		*width = gf_bs_read_u32(bs);
		*height = gf_bs_read_u32(bs);
		*OTI = GPAC_OTI_IMAGE_PNG;
		*mtype = GF_4CC('p','n','g',' ');
	}
	size = gf_bs_read_u8(bs);
	type = gf_bs_read_u32(bs);
	if ( ((size==12) && (type==GF_4CC('j','P',' ',' ') ))
		|| (type==GF_4CC('j','p','2','h') ) ) {

		if (type==GF_4CC('j','p','2','h')) {
			*OTI = GPAC_OTI_IMAGE_JPEG_2000;
			*mtype = GF_4CC('j','p','2',' ');
			goto j2k_restart;
		}

		type = gf_bs_read_u32(bs);
		if (type!=0x0D0A870A) goto exit;

		*OTI = GPAC_OTI_IMAGE_JPEG_2000;
		*mtype = GF_4CC('j','p','2',' ');

		while (gf_bs_available(bs)) {
j2k_restart:
			size = gf_bs_read_u32(bs);
			type = gf_bs_read_u32(bs);
			switch (type) {
			case GF_4CC('j','p','2','h'):
				goto j2k_restart;
			case GF_4CC('i','h','d','r'):
			{
				u16 nb_comp;
				u8 BPC, C, UnkC, IPR;
				*height = gf_bs_read_u32(bs);
				*width = gf_bs_read_u32(bs);
				nb_comp = gf_bs_read_u16(bs);
				BPC = gf_bs_read_u8(bs);
				C = gf_bs_read_u8(bs);
				UnkC = gf_bs_read_u8(bs);
				IPR = gf_bs_read_u8(bs);

				if (dsi) {
					GF_BitStream *bs_dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
					gf_bs_write_u32(bs_dsi, *height);
					gf_bs_write_u32(bs_dsi, *width);
					gf_bs_write_u16(bs_dsi, nb_comp);
					gf_bs_write_u8(bs_dsi, BPC);
					gf_bs_write_u8(bs_dsi, C);
					gf_bs_write_u8(bs_dsi, UnkC);
					gf_bs_write_u8(bs_dsi, IPR);
					gf_bs_get_content(bs_dsi, dsi, dsi_len);
					gf_bs_del(bs_dsi);
				}
				goto exit;
			}
				break;
			default:
				gf_bs_skip_bytes(bs, size-8);
				break;
			}
		}
	}

exit:
	gf_bs_seek(bs, pos);
}
示例#24
0
static GF_Err WriteInterleaved(MovieWriter *mw, GF_BitStream *bs, Bool drift_inter)
{
	GF_Err e;
	u32 i;
	GF_Box *a;
	u64 firstSize, finalSize, offset, finalOffset;
	GF_List *writers = gf_list_new();
	GF_ISOFile *movie = mw->movie;

	//first setup the writers
	e = SetupWriters(mw, writers, 1);
	if (e) goto exit;


	if (movie->is_jp2) {
		gf_bs_write_u32(bs, 12);
		gf_bs_write_u32(bs, GF_4CC('j','P',' ',' '));
		gf_bs_write_u32(bs, 0x0D0A870A);
	}
	if (movie->brand) {
		e = gf_isom_box_size((GF_Box *)movie->brand);
		if (e) goto exit;
		e = gf_isom_box_write((GF_Box *)movie->brand, bs);
		if (e) goto exit;
	}
	if (movie->pdin) {
		e = gf_isom_box_size((GF_Box *)movie->pdin);
		if (e) goto exit;
		e = gf_isom_box_write((GF_Box *)movie->pdin, bs);
		if (e) goto exit;
	}

	e = DoInterleave(mw, writers, bs, 1, gf_bs_get_position(bs), drift_inter);
	if (e) goto exit;

	firstSize = GetMoovAndMetaSize(movie, writers);
	offset = firstSize;
	if (movie->mdat && movie->mdat->dataSize) offset += 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);
	e = ShiftOffset(movie, writers, offset);
	if (e) goto exit;
	//get the size and see if it has changed (eg, we moved to 64 bit offsets)
	finalSize = GetMoovAndMetaSize(movie, writers);
	if (firstSize != finalSize) {
		//we need to remove our offsets
		ResetWriters(writers);
		finalOffset = finalSize;
		if (movie->mdat->dataSize) finalOffset += 8 + (movie->mdat->dataSize > 0xFFFFFFFF ? 8 : 0);
		//OK, now we're sure about the final size -> shift the offsets
		//we don't need to re-emulate, as the only thing that changed is the offset
		//so just shift the offset
		e = ShiftOffset(movie, writers, finalOffset - offset);
		if (e) goto exit;
		firstSize = GetMoovAndMetaSize(movie, writers);
	}
	//now write our stuff
	e = WriteMoovAndMeta(movie, writers, bs);
	if (e) goto exit;

	/*we have 8 extra bytes for large size (not computed in gf_isom_box_size) */
	if (movie->mdat && movie->mdat->dataSize) {
		if (movie->mdat->dataSize > 0xFFFFFFFF) movie->mdat->dataSize += 8;
		e = gf_isom_box_size((GF_Box *)movie->mdat);
		if (e) goto exit;
		e = gf_isom_box_write((GF_Box *)movie->mdat, bs);
		if (e) goto exit;
	}

	//we don't need the offset as we are writing...
	ResetWriters(writers);
	e = DoInterleave(mw, writers, bs, 0, 0, drift_inter);
	if (e) goto exit;

	//then the rest
	i=0;
	while ((a = (GF_Box*)gf_list_enum(movie->TopBoxes, &i))) {
		switch (a->type) {
		case GF_ISOM_BOX_TYPE_MOOV:
		case GF_ISOM_BOX_TYPE_META:
		case GF_ISOM_BOX_TYPE_FTYP:
		case GF_ISOM_BOX_TYPE_PDIN:
		case GF_ISOM_BOX_TYPE_MDAT:
			break;
		default:
			e = gf_isom_box_size(a);
			if (e) goto exit;
			e = gf_isom_box_write(a, bs);
			if (e) goto exit;
		}
	}

exit:
	CleanWriters(writers);
	gf_list_del(writers);
	return e;
}
示例#25
0
GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing, Bool progressive_mode)
{
	GF_Box *a;
	u64 totSize;
	GF_Err e = GF_OK;

	totSize = 0;


#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
	/*restart from where we stopped last*/
	totSize = mov->current_top_box_start;
	gf_bs_seek(mov->movieFileMap->bs, mov->current_top_box_start);
#endif


	/*while we have some data, parse our boxes*/
	while (gf_bs_available(mov->movieFileMap->bs)) {
		*bytesMissing = 0;
#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
		mov->current_top_box_start = gf_bs_get_position(mov->movieFileMap->bs);
#endif

		e = gf_isom_parse_root_box(&a, mov->movieFileMap->bs, bytesMissing, progressive_mode);

		if (e >= 0) {
			e = GF_OK;
		} else if (e == GF_ISOM_INCOMPLETE_FILE) {
			/*our mdat is uncomplete, only valid for READ ONLY files...*/
			if (mov->openMode != GF_ISOM_OPEN_READ) {
				return GF_ISOM_INVALID_FILE;
			}
			return e;
		} else {
			return e;
		}

		switch (a->type) {
		/*MOOV box*/
		case GF_ISOM_BOX_TYPE_MOOV:
			if (mov->moov) return GF_ISOM_INVALID_FILE;
			mov->moov = (GF_MovieBox *)a;
			/*set our pointer to the movie*/
			mov->moov->mov = mov;
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
            if (mov->moov->mvex) mov->moov->mvex->mov = mov;
#endif
            e = gf_list_add(mov->TopBoxes, a);
			if (e) return e;
			totSize += a->size;
			break;

		/*META box*/
		case GF_ISOM_BOX_TYPE_META:
			if (mov->meta) return GF_ISOM_INVALID_FILE;
			mov->meta = (GF_MetaBox *)a;
			e = gf_list_add(mov->TopBoxes, a);
			if (e) return e;
			totSize += a->size;
			break;

		/*we only keep the MDAT in READ for dump purposes*/
		case GF_ISOM_BOX_TYPE_MDAT:
			totSize += a->size;
			if (mov->openMode == GF_ISOM_OPEN_READ) {
				if (!mov->mdat) {
					mov->mdat = (GF_MediaDataBox *) a;
					e = gf_list_add(mov->TopBoxes, mov->mdat);
					if (e) return e;
				}
#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
				else if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) gf_list_add(mov->TopBoxes, a);
#endif
				else gf_isom_box_del(a);
			}
			/*if we don't have any MDAT yet, create one (edit-write mode)
			We only work with one mdat, but we're puting it at the place
			of the first mdat found when opening a file for editing*/
			else if (!mov->mdat && (mov->openMode != GF_ISOM_OPEN_READ) && (mov->openMode != GF_ISOM_OPEN_CAT_FRAGMENTS)) {
				gf_isom_box_del(a);
				mov->mdat = (GF_MediaDataBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MDAT);
				e = gf_list_add(mov->TopBoxes, mov->mdat);
				if (e) return e;
			} else {
				gf_isom_box_del(a);
			}
			break;
		case GF_ISOM_BOX_TYPE_FTYP:
			/*ONE AND ONLY ONE FTYP*/
			if (mov->brand) {
				gf_isom_box_del(a);
				return GF_ISOM_INVALID_FILE;
			}
			mov->brand = (GF_FileTypeBox *)a;
			totSize += a->size;
			e = gf_list_add(mov->TopBoxes, a);
			break;

		case GF_ISOM_BOX_TYPE_PDIN:
			/*ONE AND ONLY ONE PDIN*/
			if (mov->pdin) {
				gf_isom_box_del(a);
				return GF_ISOM_INVALID_FILE;
			}
			mov->pdin = (GF_ProgressiveDownloadBox *) a;
			totSize += a->size;
			e = gf_list_add(mov->TopBoxes, a);
			break;


#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
		case GF_ISOM_BOX_TYPE_STYP:
			if (((GF_SegmentTypeBox *)a)->majorBrand == GF_4CC('i', 's', 's', 's') ||
				((GF_SegmentTypeBox *)a)->majorBrand == GF_4CC('i', 'm', 's', 's')) mov->is_index_segment = 1;

		case GF_ISOM_BOX_TYPE_SIDX:
			totSize += a->size;
			if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) {
				e = gf_list_add(mov->TopBoxes, a);
			} else {
				gf_isom_box_del(a);
			}
			break;

		case GF_ISOM_BOX_TYPE_MOOF:
			((GF_MovieFragmentBox *)a)->mov = mov;

			totSize += a->size;
            mov->moof = (GF_MovieFragmentBox *) a;
			/*read & debug: store at root level*/
			if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) {
                gf_list_add(mov->TopBoxes, a);
			} else if (mov->openMode==GF_ISOM_OPEN_CAT_FRAGMENTS) {
				mov->NextMoofNumber = mov->moof->mfhd->sequence_number+1;
				mov->moof = NULL;
				gf_isom_box_del(a);
			} else {
				/*merge all info*/
				e = MergeFragment((GF_MovieFragmentBox *)a, mov);
				gf_isom_box_del(a);
				if (e) {
					GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Error merging fragment: %s\n", gf_error_to_string(e) ));
				}
			}
			break;
#endif
		case GF_4CC('j','P',' ',' '):
		{
			GF_UnknownBox *box = (GF_UnknownBox*)a;
			u8 *c = box->data;
			if ((box->dataSize==4) 
				&& (GF_4CC(c[0],c[1],c[2],c[3])==(u32)0x0D0A870A)) 
				 mov->is_jp2 = 1;

			gf_isom_box_del(a);
		}
			break;

		default:
			totSize += a->size;
			e = gf_list_add(mov->TopBoxes, a);
			break;
		}

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
//		mov->current_top_box_start = gf_bs_get_position(mov->movieFileMap->bs);
#endif
	}

	/*we need at least moov or meta*/
	if (!mov->moov && !mov->meta 
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
        && !mov->moof && !mov->is_index_segment
#endif
        ) return GF_ISOM_INVALID_FILE;
	/*we MUST have movie header*/
	if (mov->moov && !mov->moov->mvhd) return GF_ISOM_INVALID_FILE;
	/*we MUST have meta handler*/
	if (mov->meta && !mov->meta->handler) return GF_ISOM_INVALID_FILE;

#ifndef GPAC_DISABLE_ISOM_WRITE

	if (mov->moov) {
		/*set the default interleaving time*/
		mov->interleavingTime = mov->moov->mvhd->timeScale;

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
		/*in edit mode with successfully loaded fragments, delete all fragment signaling since
		file is no longer fragmented*/
		if ((mov->openMode > GF_ISOM_OPEN_READ) && (mov->openMode != GF_ISOM_OPEN_CAT_FRAGMENTS) && mov->moov->mvex) {
			gf_isom_box_del((GF_Box *)mov->moov->mvex);
			mov->moov->mvex = NULL;
		}
#endif

	}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

	return GF_OK;
}
示例#26
0
GF_Err gp_rtp_builder_do_mpeg4(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize)
{
	char *sl_buffer, *payl_buffer;
	u32 sl_buffer_size, payl_buffer_size;
	u32 auh_size_tmp, bytesLeftInPacket, infoSize, pckSize;
	u64 pos;
	u8 flush_pck, no_split;

	flush_pck = 0;

	bytesLeftInPacket = data_size;
	/*flush everything*/
	if (!data) {
		if (builder->payload) goto flush_packet;
		return GF_OK;
	}
	if (builder->payload && builder->force_flush) goto flush_packet;

	//go till done
	while (bytesLeftInPacket) {
		no_split = 0;

		if (builder->sl_header.accessUnitStartFlag) {
			//init SL
			if (builder->sl_header.compositionTimeStamp != builder->sl_header.decodingTimeStamp) {
				builder->sl_header.decodingTimeStampFlag = 1;
			}
			builder->sl_header.compositionTimeStampFlag = 1;
			builder->sl_header.accessUnitLength = FullAUSize;

			//init some vars - based on the available size and the TS
			//we decide if we go with the same RTP TS serie or not
			if (builder->payload) {
				//don't store more than what we can (that is 2^slMap->CTSDelta - 1)
				if ( (builder->flags & GP_RTP_PCK_SIGNAL_TS)
					&& (builder->sl_header.compositionTimeStamp - builder->rtp_header.TimeStamp >= (u32) ( 1 << builder->slMap.CTSDeltaLength) ) ) {
					goto flush_packet;
				}
				//don't split AU if # TS , start a new RTP pck
				if (builder->sl_header.compositionTimeStamp != builder->rtp_header.TimeStamp)
					no_split = 1;
			}
		}

		/*new RTP Packet*/
		if (!builder->payload) {
			/*first SL in RTP*/
			builder->first_sl_in_rtp = 1;

			/*if this is the end of an AU we will set it to 0 as soon as an AU is splited*/
			builder->rtp_header.Marker = 1;
			builder->rtp_header.PayloadType = builder->PayloadType;
			builder->rtp_header.SequenceNumber += 1;

			builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp;
			/*prepare the mapped headers*/
			builder->pck_hdr = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
			builder->payload = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
			pckSize = infoSize = 0;
			builder->bytesInPacket = 0;

			/*in multiSL there is a MSLHSize structure on 2 bytes*/
			builder->auh_size = 0;
			if (builder->has_AU_header) {
				builder->auh_size = 16;
				gf_bs_write_int(builder->pck_hdr, 0, 16);
			}
			flush_pck = 0;
			/*and create packet*/
			builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);
		}

		//make sure we are not interleaving too much - this should never happen actually
		if (builder->slMap.IndexDeltaLength
			&& !builder->first_sl_in_rtp
			&& (builder->sl_header.AU_sequenceNumber - builder->last_au_sn >= (u32) 1<<builder->slMap.IndexDeltaLength)) {
			//we cannot write this packet here
			goto flush_packet;
		}
		/*check max ptime*/
		if (builder->max_ptime && ( (u32) builder->sl_header.compositionTimeStamp >= builder->rtp_header.TimeStamp + builder->max_ptime) )
			goto flush_packet;

		auh_size_tmp = gf_rtp_build_au_hdr_size(builder, &builder->sl_header);

		infoSize = auh_size_tmp + builder->auh_size;
		infoSize /= 8;
		/*align*/
		if ( (builder->auh_size + auh_size_tmp) % 8) infoSize += 1;


		if (bytesLeftInPacket + infoSize + builder->bytesInPacket <= builder->Path_MTU) {
			//End of our data chunk
			pckSize = bytesLeftInPacket;
			builder->sl_header.accessUnitEndFlag = IsAUEnd;

			builder->auh_size += auh_size_tmp;

			builder->sl_header.paddingFlag = builder->sl_header.paddingBits ? 1 : 0;
		} else {

			//AU cannot fit in packet. If no split, start a new packet
			if (no_split) goto flush_packet;

			builder->auh_size += auh_size_tmp;

			pckSize = builder->Path_MTU - (infoSize + builder->bytesInPacket);
			//that's the end of the rtp packet
			flush_pck = 1;
			//but not of the AU -> marker is 0
			builder->rtp_header.Marker = 0;
		}

		gf_rtp_build_au_hdr_write(builder, pckSize, builder->rtp_header.TimeStamp);

		//notify the user of our data structure
		if (builder->OnDataReference)
			builder->OnDataReference(builder->cbk_obj, pckSize, data_size - bytesLeftInPacket);
		else
			gf_bs_write_data(builder->payload, data + (data_size - bytesLeftInPacket), pckSize);


		bytesLeftInPacket -= pckSize;
		builder->bytesInPacket += pckSize;
		/*update IV*/
		builder->IV += pckSize;
		builder->sl_header.paddingFlag = 0;
		builder->sl_header.accessUnitStartFlag = 0;

		//we are splitting a payload, auto increment SL seq num
		if (bytesLeftInPacket) {
			builder->sl_header.packetSequenceNumber += 1;
		} else if (! (builder->flags & GP_RTP_PCK_USE_MULTI) ) {
			builder->rtp_header.Marker = 1;
			flush_pck = 1;
		}

		//first SL in RTP is done
		builder->first_sl_in_rtp = 0;

		//store current sl
		builder->last_au_sn = builder->sl_header.AU_sequenceNumber;

		if (!flush_pck) continue;

		//done with the packet
flush_packet:

		gf_bs_align(builder->pck_hdr);

		/*no aux data yet*/
		if (builder->slMap.AuxiliaryDataSizeLength)	{
			//write RSLH after the MSLH
			gf_bs_write_int(builder->pck_hdr, 0, builder->slMap.AuxiliaryDataSizeLength);
		}
		/*rewrite the size header*/
		if (builder->has_AU_header) {
			pos = gf_bs_get_position(builder->pck_hdr);
			gf_bs_seek(builder->pck_hdr, 0);
			builder->auh_size -= 16;
			gf_bs_write_int(builder->pck_hdr, builder->auh_size, 16);
			gf_bs_seek(builder->pck_hdr, pos);
		}

		sl_buffer = NULL;
		gf_bs_get_content(builder->pck_hdr, &sl_buffer, &sl_buffer_size);
		//delete our bitstream
		gf_bs_del(builder->pck_hdr);
		builder->pck_hdr = NULL;

		payl_buffer = NULL;
		payl_buffer_size = 0;
		if (!builder->OnDataReference)
			gf_bs_get_content(builder->payload, &payl_buffer, &payl_buffer_size);

		gf_bs_del(builder->payload);
		builder->payload = NULL;

		/*notify header*/
		builder->OnData(builder->cbk_obj, sl_buffer, sl_buffer_size, 1);
		/*notify payload*/
		if (payl_buffer) {
			builder->OnData(builder->cbk_obj, payl_buffer, payl_buffer_size, 0);
			gf_free(payl_buffer);
		}
		/*flush packet*/
		builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);
		gf_free(sl_buffer);
	}
	//packet is done, update AU markers
	if (IsAUEnd) {
		builder->sl_header.accessUnitStartFlag = 1;
		builder->sl_header.accessUnitEndFlag = 0;
	}
	return GF_OK;
}
示例#27
0
文件: ait.c 项目: gorinje/gpac-svn
static GF_Err gf_m2ts_decode_ait(GF_M2TS_AIT *ait, char  *data, u32 data_size, u32 table_id)
{

	GF_BitStream *bs;
	u8 temp_descriptor_tag;
	u32 data_shift, app_desc_data_shift, ait_app_data_shift;
	u32 nb_of_protocol;

	data_shift = 0;
	temp_descriptor_tag = 0;
	ait_app_data_shift = 0;
	bs = gf_bs_new(data,data_size,GF_BITSTREAM_READ);

	ait->common_descriptors = gf_list_new();
	if(ait->common_descriptors == NULL){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Error during common_descriptors list initialization, abording processing \n"));
		return GF_CORRUPTED_DATA;
	}
	ait->application_decoded = gf_list_new();
	if(ait->application_decoded == NULL){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Error during application list initialization, abording processing \n"));
		return GF_CORRUPTED_DATA;
	}

	ait->table_id = gf_bs_read_int(bs,8);	
	ait->section_syntax_indicator = gf_bs_read_int(bs,1);
	gf_bs_read_int(bs,3);
	ait->section_length = gf_bs_read_int(bs,12);	
	if( (data[1] & 0x0C) != 0){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] section length is not correct abroding \n"));
	}else if( ait->section_length > AIT_SECTION_LENGTH_MAX){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] section length should not exceed 1021. Wrong section, abording processing \n"));
	}
	ait->test_application_flag = gf_bs_read_int(bs,1);
	if(ait->test_application_flag == 1){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] test application flag is at 1. API transmitted for testing, abording processing \n"));
		return GF_CORRUPTED_DATA;
	}
	ait->application_type = gf_bs_read_int(bs,15);	
	if(ait->application_type != APPLICATION_TYPE_HTTP_APPLICATION){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] application type should 0x10. Wrong section, abording processing \n"));
		return GF_CORRUPTED_DATA;
	}
	gf_bs_read_int(bs,2);
	ait->version_number = gf_bs_read_int(bs,5);

	ait->current_next_indicator = gf_bs_read_int(bs,1);	
	if(!ait->current_next_indicator){
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] current next indicator should be at 1 \n"));
		return GF_CORRUPTED_DATA;
	}
	ait->section_number = gf_bs_read_int(bs,8);
	ait->last_section_number = gf_bs_read_int(bs,8);	
	gf_bs_read_int(bs,4);/* bit shifting */
	ait->common_descriptors_length = gf_bs_read_int(bs,12);	
	gf_bs_read_int(bs,(unsigned int)ait->common_descriptors_length/8);
	gf_bs_read_int(bs,4);/* bit shifting */	
	ait->application_loop_length = gf_bs_read_int(bs,12);

	data_shift = (u32)(gf_bs_get_position(bs)) + ait->common_descriptors_length/8;

	while (ait_app_data_shift < ait->application_loop_length) {

		GF_M2TS_AIT_APPLICATION_DECODE* application;
		GF_SAFEALLOC(application,GF_M2TS_AIT_APPLICATION_DECODE);
		application->application_descriptors = gf_list_new();
		application->index_app_desc_id = 0;

		/* application loop */
		application->organisation_id = gf_bs_read_int(bs,32);	
		application->application_id= gf_bs_read_int(bs,16);
		application->application_control_code= gf_bs_read_int(bs,8);
		gf_bs_read_int(bs,4);/* bit shifting */
		application->application_descriptors_loop_length= gf_bs_read_int(bs,12);		

		ait_app_data_shift += 9;
		app_desc_data_shift = 0;
		nb_of_protocol = 0;

		while (app_desc_data_shift< application->application_descriptors_loop_length) {
			temp_descriptor_tag = gf_bs_read_int(bs,8);
			switch (temp_descriptor_tag) {
				case APPLICATION_DESCRIPTOR:
					{
						u64 pre_processing_pos;
						u8 i;
						GF_M2TS_APPLICATION_DESCRIPTOR *application_descriptor;
						GF_SAFEALLOC(application_descriptor, GF_M2TS_APPLICATION_DESCRIPTOR);
						application_descriptor->descriptor_tag = temp_descriptor_tag;
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						application_descriptor->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						application_descriptor->application_profiles_length = gf_bs_read_int(bs,8);
						application_descriptor->application_profile = gf_bs_read_int(bs,16);
						application_descriptor->version_major = gf_bs_read_int(bs,8);
						application_descriptor->version_minor = gf_bs_read_int(bs,8);
						application_descriptor->version_micro = gf_bs_read_int(bs,8);
						application_descriptor->service_bound_flag = gf_bs_read_int(bs,1);
						application_descriptor->visibility = gf_bs_read_int(bs,2);
						gf_bs_read_int(bs,5); /*bit shift*/
						application_descriptor->application_priority = gf_bs_read_int(bs,8);
						if (nb_of_protocol > 0) {
							for (i=0; i<nb_of_protocol; i++) {						
								application_descriptor->transport_protocol_label[i] = gf_bs_read_int(bs,8);
							}
						} else {
							application_descriptor->transport_protocol_label[0] = gf_bs_read_int(bs,8);
						}
						if (pre_processing_pos+application_descriptor->descriptor_length != gf_bs_get_position(bs) || application_descriptor->application_profile == 2 /* PVR feature */) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),application_descriptor->descriptor_length));
							gf_free(application_descriptor);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,application_descriptor);
						app_desc_data_shift += (2+ application_descriptor->descriptor_length);
						break;
					}
				case APPLICATION_NAME_DESCRIPTOR:
					{
						u64 pre_processing_pos;
						GF_M2TS_APPLICATION_NAME_DESCRIPTOR* name_descriptor;
						GF_SAFEALLOC(name_descriptor, GF_M2TS_APPLICATION_NAME_DESCRIPTOR);
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						name_descriptor->descriptor_tag = temp_descriptor_tag;
						name_descriptor->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						name_descriptor->ISO_639_language_code = gf_bs_read_int(bs,24);
						name_descriptor->application_name_length = gf_bs_read_int(bs,8);
						name_descriptor->application_name_char = (char*) gf_calloc(name_descriptor->application_name_length+1,sizeof(char));
						gf_bs_read_data(bs,name_descriptor->application_name_char,name_descriptor->application_name_length);
						name_descriptor->application_name_char[name_descriptor->application_name_length] = 0 ;
						if (pre_processing_pos+name_descriptor->descriptor_length != gf_bs_get_position(bs)) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),name_descriptor->descriptor_length));
							gf_free(name_descriptor->application_name_char);
							gf_free(name_descriptor);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,name_descriptor);
						app_desc_data_shift += (2+ name_descriptor->descriptor_length);
						break;
					}
				case TRANSPORT_PROTOCOL_DESCRIPTOR:
					{
						u64 pre_processing_pos;
						GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR* protocol_descriptor;
						GF_SAFEALLOC(protocol_descriptor, GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR);
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						nb_of_protocol++;
						protocol_descriptor->descriptor_tag = temp_descriptor_tag;
						protocol_descriptor->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						protocol_descriptor->protocol_id = gf_bs_read_int(bs,16);
						protocol_descriptor->transport_protocol_label = gf_bs_read_int(bs,8);
						switch (protocol_descriptor->protocol_id) {
				case CAROUSEL:
					{
						GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE* Carousel_selector_byte;
						GF_SAFEALLOC(Carousel_selector_byte, GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE);
						Carousel_selector_byte->remote_connection = gf_bs_read_int(bs,1);
						gf_bs_read_int(bs,7); /* bit shifting */
						if (Carousel_selector_byte->remote_connection) {
							Carousel_selector_byte->original_network_id = gf_bs_read_int(bs,16);
							Carousel_selector_byte->transport_stream_id = gf_bs_read_int(bs,16);
							Carousel_selector_byte->service_id = gf_bs_read_int(bs,16);
						}
						Carousel_selector_byte->component_tag = gf_bs_read_int(bs,8);
						protocol_descriptor->selector_byte = Carousel_selector_byte;
						break;
					}
				case TRANSPORT_HTTP:
					{					
						u32 i;								
						GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE* Transport_http_selector_byte;
						GF_SAFEALLOC(Transport_http_selector_byte, GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE);					
						Transport_http_selector_byte->URL_base_length = gf_bs_read_int(bs,8);
						//fprintf(stderr, "Transport_http_selector_byte->URL_base_length %d \n",Transport_http_selector_byte->URL_base_length);
						Transport_http_selector_byte->URL_base_byte = (char*)gf_calloc(Transport_http_selector_byte->URL_base_length+1,sizeof(char));
						gf_bs_read_data(bs,Transport_http_selector_byte->URL_base_byte ,(u32)(Transport_http_selector_byte->URL_base_length));
						Transport_http_selector_byte->URL_base_byte[Transport_http_selector_byte->URL_base_length] = 0;
						Transport_http_selector_byte->URL_extension_count = gf_bs_read_int(bs,8);
						if (Transport_http_selector_byte->URL_extension_count) {
							Transport_http_selector_byte->URL_extentions = (GF_M2TS_TRANSPORT_HTTP_URL_EXTENTION*) gf_calloc(Transport_http_selector_byte->URL_extension_count,sizeof(GF_M2TS_TRANSPORT_HTTP_URL_EXTENTION));
							for (i=0; i < Transport_http_selector_byte->URL_extension_count;i++) {
								Transport_http_selector_byte->URL_extentions[i].URL_extension_length = gf_bs_read_int(bs,8);
								Transport_http_selector_byte->URL_extentions[i].URL_extension_byte = (char*)gf_calloc(Transport_http_selector_byte->URL_extentions[i].URL_extension_length+1,sizeof(char));
								gf_bs_read_data(bs,Transport_http_selector_byte->URL_extentions[i].URL_extension_byte,(u32)(Transport_http_selector_byte->URL_extentions[i].URL_extension_length));
								Transport_http_selector_byte->URL_extentions[i].URL_extension_byte[Transport_http_selector_byte->URL_extentions[i].URL_extension_length] = 0;
							}
						}
						protocol_descriptor->selector_byte = Transport_http_selector_byte;
						break;
					}
				default:
					{
						GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Protocol ID %d unsupported, ignoring the selector byte \n",protocol_descriptor->protocol_id));
					}
						}
						if (pre_processing_pos+protocol_descriptor->descriptor_length != gf_bs_get_position(bs)) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),protocol_descriptor->descriptor_length));
							if (protocol_descriptor->protocol_id == CAROUSEL) {						
								GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE* Carousel_selector_byte = (GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE*) protocol_descriptor->selector_byte;								
								gf_free(Carousel_selector_byte);								
							} else if(protocol_descriptor->protocol_id ==TRANSPORT_HTTP) {
								u32 i;
								GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE* Transport_http_selector_byte = (GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE*) protocol_descriptor->selector_byte;								
								gf_free(Transport_http_selector_byte->URL_base_byte);
								for(i = 0; i < Transport_http_selector_byte->URL_extension_count;i++){										
									gf_free(Transport_http_selector_byte->URL_extentions[i].URL_extension_byte);
								}
								gf_free(Transport_http_selector_byte);						
							}
							gf_free(protocol_descriptor);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,protocol_descriptor);					
						app_desc_data_shift += (2+ protocol_descriptor->descriptor_length);
						break;
					}
				case SIMPLE_APPLICATION_LOCATION_DESCRIPTOR:
					{
						u64 pre_processing_pos;					
						GF_M2TS_SIMPLE_APPLICATION_LOCATION* Simple_application_location;
						GF_SAFEALLOC(Simple_application_location, GF_M2TS_SIMPLE_APPLICATION_LOCATION);
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						Simple_application_location->descriptor_tag = temp_descriptor_tag;
						Simple_application_location->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						Simple_application_location->initial_path_bytes = (char*)gf_calloc(Simple_application_location->descriptor_length+1,sizeof(char));
						gf_bs_read_data(bs,Simple_application_location->initial_path_bytes ,(u32)(Simple_application_location->descriptor_length));
						Simple_application_location->initial_path_bytes[Simple_application_location->descriptor_length] = 0;
						if (pre_processing_pos+Simple_application_location->descriptor_length != gf_bs_get_position(bs)) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),Simple_application_location->descriptor_length));
							gf_free(Simple_application_location->initial_path_bytes);
							gf_free(Simple_application_location);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,Simple_application_location);
						app_desc_data_shift += (2+ Simple_application_location->descriptor_length);
						break;
					}
				case APPLICATION_USAGE_DESCRIPTOR:
					{
						u64 pre_processing_pos;
						GF_M2TS_APPLICATION_USAGE* Application_usage;
						GF_SAFEALLOC(Application_usage, GF_M2TS_APPLICATION_USAGE);
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						Application_usage->descriptor_tag = temp_descriptor_tag;
						Application_usage->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						Application_usage->usage_type = gf_bs_read_int(bs,8);
						if (pre_processing_pos+Application_usage->descriptor_length != gf_bs_get_position(bs)) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),Application_usage->descriptor_length));
							gf_free(Application_usage);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,Application_usage);
						app_desc_data_shift += (2+ Application_usage->descriptor_length);
						break;
					}
				case APPLICATION_BOUNDARY_DESCRIPTOR:
					{
						u64 pre_processing_pos;
						u32 i;
						GF_M2TS_APPLICATION_BOUNDARY_DESCRIPTOR* boundary_descriptor;
						GF_SAFEALLOC(boundary_descriptor, GF_M2TS_APPLICATION_BOUNDARY_DESCRIPTOR);
						application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag;
						application->index_app_desc_id++;
						boundary_descriptor->descriptor_tag = temp_descriptor_tag;
						boundary_descriptor->descriptor_length = gf_bs_read_int(bs,8);
						pre_processing_pos = gf_bs_get_position(bs);
						boundary_descriptor->boundary_extension_count = gf_bs_read_int(bs,8);
						if (boundary_descriptor->boundary_extension_count > 0) {
							boundary_descriptor->boundary_extension_info = (GF_M2TS_APPLICATION_BOUNDARY_EXTENSION_INFO*)gf_calloc(boundary_descriptor->boundary_extension_count,sizeof(GF_M2TS_APPLICATION_BOUNDARY_EXTENSION_INFO));
							for (i=0;i<boundary_descriptor->boundary_extension_count;i++) {
								boundary_descriptor->boundary_extension_info[i].boundary_extension_length = gf_bs_read_int(bs,8);
								if (boundary_descriptor->boundary_extension_info[i].boundary_extension_length > 0) {
									boundary_descriptor->boundary_extension_info[i].boundary_extension_byte = (char*)gf_calloc(boundary_descriptor->boundary_extension_info[i].boundary_extension_length+1,sizeof(char));
									gf_bs_read_data(bs,boundary_descriptor->boundary_extension_info[i].boundary_extension_byte ,(u32)(boundary_descriptor->boundary_extension_info[i].boundary_extension_length));
									boundary_descriptor->boundary_extension_info[i].boundary_extension_byte[boundary_descriptor->boundary_extension_info[i].boundary_extension_length] = 0;
								}
							}
						}
						if (pre_processing_pos+boundary_descriptor->descriptor_length != gf_bs_get_position(bs)) {
							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) -  pre_processing_pos),boundary_descriptor->descriptor_length));
							if (boundary_descriptor->boundary_extension_count > 0) {
								u32 i;
								for (i=0;i<boundary_descriptor->boundary_extension_count;i++) {
									if (boundary_descriptor->boundary_extension_info[i].boundary_extension_length > 0) {
										gf_free(boundary_descriptor->boundary_extension_info[i].boundary_extension_byte);
									}
								}
								gf_free(boundary_descriptor->boundary_extension_info);
							}
							gf_free(boundary_descriptor);
							return GF_CORRUPTED_DATA;
						}
						gf_list_add(application->application_descriptors,boundary_descriptor);
						app_desc_data_shift += (2+ boundary_descriptor->descriptor_length);
						break;					
					}
				default:
					{
						u8 length;
						GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor tag %d unknown, ignoring the descriptor \n",temp_descriptor_tag));
						/* get descriptor's length */
						length = gf_bs_read_int(bs,8);
						/* bit shifting (eq descriptor's length)*/
						gf_bs_read_int(bs,8*length);					
					}

			}

		}
		ait_app_data_shift += application->application_descriptors_loop_length; 
		gf_list_add(ait->application_decoded,application);		
	}

	data_shift +=ait->application_loop_length;
	ait->CRC_32 = gf_bs_read_int(bs,32);
	data_shift += 4;


	if (data_shift != data_size) {
		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] AIT processed length error. Difference between byte shifting %d and data size %d \n",data_shift,data_size));
		return GF_CORRUPTED_DATA;
	}

	return GF_OK;
}
示例#28
0
文件: main.c 项目: ARSekkat/gpac
void RS_Deinterleaver(GF_BitStream *bs, char *out_name)
{
	u8 rs0[204], rs1[204], rs2[204], rs3[204], rs4[204], rs5[204], rs6[204], rs7[204], rs8[204], rs9[204], rs10[204], rs11[204];
	u8 *rs[12] = { rs0, rs1, rs2, rs3, rs4, rs5, rs6, rs7, rs8, rs9, rs10, rs11 };
	u8 *tmp;
	u8 buf[204];
	u32 i;
	u64 bs_data;
	u32 k = 0;

	memset(rs[0], 0, 204);
	memset(rs[1], 0, 204);
	memset(rs[2], 0, 204);
	memset(rs[3], 0, 204);
	memset(rs[4], 0, 204);
	memset(rs[5], 0, 204);
	memset(rs[6], 0, 204);
	memset(rs[7], 0, 204);
	memset(rs[8], 0, 204);
	memset(rs[9], 0, 204);
	memset(rs[10], 0, 204);
	memset(rs[11], 0, 204);

	bs_data = gf_bs_available(bs);
	while (bs_data > 204) {
		u64 pos;
		k++;
//		printf("TS Packet Number: %d\r", k);

		pos = gf_bs_get_position(bs);
		gf_bs_read_data(bs, buf, 204);
		bs_data = gf_bs_available(bs);

		while ((buf[0] != 0x47) && (bs_data > 0)) {
			printf("error in input TS %d\n", k);
			//return;
			pos++;
			gf_bs_seek(bs, pos);
			gf_bs_read_data(bs, buf, 204);
			bs_data = gf_bs_available(bs);
		}

		for (i=0; i<(17*12); i+=12) { // 1 paquet
			rs[0][i]     = buf[i];
			rs[1][i+1]   = buf[i+1];
			rs[2][i+2]	 = buf[i+2];
			rs[3][i+3]   = buf[i+3];
			rs[4][i+4]   = buf[i+4];
			rs[5][i+5]   = buf[i+5];
			rs[6][i+6]   = buf[i+6];
			rs[7][i+7]   = buf[i+7];
			rs[8][i+8]   = buf[i+8];
			rs[9][i+9]   = buf[i+9];
			rs[10][i+10] = buf[i+10];
			rs[11][i+11] = buf[i+11];
		}
		if (k >= 12) {
			if (rs[11][0] != 0x47) {
				printf("error in output TS\n");
			} else {
				save_ts(out_name, rs[11]);
			}
		}
		tmp = rs[11];
		rs[11] = rs[10];
		rs[10] = rs[9];
		rs[9] = rs[8];
		rs[8] = rs[7];
		rs[7] = rs[6];
		rs[6] = rs[5];
		rs[5] = rs[4];
		rs[4] = rs[3];
		rs[3] = rs[2];
		rs[2] = rs[1];
		rs[1] = rs[0];
		rs[0] = tmp;
	}
}
示例#29
0
GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing, Bool progressive_mode)
{
    GF_Box *a;
    u64 totSize;
    GF_Err e = GF_OK;

    totSize = 0;


#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
    if (mov->single_moof_mode && mov->single_moof_state == 2) {
        return e;
    }

    /*restart from where we stopped last*/
    totSize = mov->current_top_box_start;
    gf_bs_seek(mov->movieFileMap->bs, mov->current_top_box_start);

#endif


    /*while we have some data, parse our boxes*/
    while (gf_bs_available(mov->movieFileMap->bs)) {
        *bytesMissing = 0;
#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
        mov->current_top_box_start = gf_bs_get_position(mov->movieFileMap->bs);
        GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Current top box start before parsing %d\n", mov->current_top_box_start));
#endif

        e = gf_isom_parse_root_box(&a, mov->movieFileMap->bs, bytesMissing, progressive_mode);

        if (e >= 0) {
            e = GF_OK;
        } else if (e == GF_ISOM_INCOMPLETE_FILE) {
            /*our mdat is uncomplete, only valid for READ ONLY files...*/
            if (mov->openMode != GF_ISOM_OPEN_READ) {
                GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Incomplete MDAT while file is not read-only\n"));
                return GF_ISOM_INVALID_FILE;
            }
            return e;
        } else {
            return e;
        }

        switch (a->type) {
        /*MOOV box*/
        case GF_ISOM_BOX_TYPE_MOOV:
            if (mov->moov) {
                GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Duplicate MOOV detected!\n"));
                return GF_ISOM_INVALID_FILE;
            }
            mov->moov = (GF_MovieBox *)a;
            /*set our pointer to the movie*/
            mov->moov->mov = mov;
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
            if (mov->moov->mvex) mov->moov->mvex->mov = mov;
#endif
            e = gf_list_add(mov->TopBoxes, a);
            if (e) {
                return e;
            }
            totSize += a->size;
            break;

        /*META box*/
        case GF_ISOM_BOX_TYPE_META:
            if (mov->meta) {
                GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Duplicate META detected!\n"));
                return GF_ISOM_INVALID_FILE;
            }
            mov->meta = (GF_MetaBox *)a;
            e = gf_list_add(mov->TopBoxes, a);
            if (e) {
                return e;
            }
            totSize += a->size;
            break;

        /*we only keep the MDAT in READ for dump purposes*/
        case GF_ISOM_BOX_TYPE_MDAT:
            totSize += a->size;
            if (mov->openMode == GF_ISOM_OPEN_READ) {
                if (!mov->mdat) {
                    mov->mdat = (GF_MediaDataBox *) a;
                    e = gf_list_add(mov->TopBoxes, mov->mdat);
                    if (e) {
                        return e;
                    }
                }
#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
                else if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) gf_list_add(mov->TopBoxes, a);
#endif
                else gf_isom_box_del(a);
            }
            /*if we don't have any MDAT yet, create one (edit-write mode)
            We only work with one mdat, but we're puting it at the place
            of the first mdat found when opening a file for editing*/
            else if (!mov->mdat && (mov->openMode != GF_ISOM_OPEN_READ) && (mov->openMode != GF_ISOM_OPEN_CAT_FRAGMENTS)) {
                gf_isom_box_del(a);
                mov->mdat = (GF_MediaDataBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MDAT);
                e = gf_list_add(mov->TopBoxes, mov->mdat);
                if (e) {
                    return e;
                }
            } else {
                gf_isom_box_del(a);
            }
            break;
        case GF_ISOM_BOX_TYPE_FTYP:
            /*ONE AND ONLY ONE FTYP*/
            if (mov->brand) {
                gf_isom_box_del(a);
                GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Duplicate FTYP detected!\n"));
                return GF_ISOM_INVALID_FILE;
            }
            mov->brand = (GF_FileTypeBox *)a;
            totSize += a->size;
            e = gf_list_add(mov->TopBoxes, a);
            break;

        case GF_ISOM_BOX_TYPE_PDIN:
            /*ONE AND ONLY ONE PDIN*/
            if (mov->pdin) {
                gf_isom_box_del(a);
                GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Duplicate PDIN detected!\n"));
                return GF_ISOM_INVALID_FILE;
            }
            mov->pdin = (GF_ProgressiveDownloadBox *) a;
            totSize += a->size;
            e = gf_list_add(mov->TopBoxes, a);
            break;


#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
        case GF_ISOM_BOX_TYPE_STYP:
        {
            u32 brand = ((GF_SegmentTypeBox *)a)->majorBrand;
            switch (brand) {
            case GF_4CC('s', 'i', 's', 'x'):
            case GF_4CC('r', 'i', 's', 'x'):
            case GF_4CC('s', 's', 's', 's'):
                mov->is_index_segment = GF_TRUE;
                break;
            default:
                break;
            }
        }
        /*fall-through*/

        case GF_ISOM_BOX_TYPE_SIDX:
            totSize += a->size;
            if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) {
                e = gf_list_add(mov->TopBoxes, a);
            } else {
                gf_isom_box_del(a);
            }
            break;

        case GF_ISOM_BOX_TYPE_MOOF:
            if (!mov->moov) {
                GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Movie fragment but no moov (yet) - possibly broken parsing!\n"));
            }
            if (mov->single_moof_mode) {
                mov->single_moof_state++;
                if (mov->single_moof_state > 1) {
                    gf_isom_box_del(a);
                    return GF_OK;
                }
            }
            ((GF_MovieFragmentBox *)a)->mov = mov;

            totSize += a->size;
            mov->moof = (GF_MovieFragmentBox *) a;
            /*read & debug: store at root level*/
            if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) {
                u32 k;
                gf_list_add(mov->TopBoxes, a);
                /*also update pointers to trex for debug*/
                if (mov->moov) {
                    for (k=0; k<gf_list_count(mov->moof->TrackList); k++) {
                        GF_TrackFragmentBox *traf = gf_list_get(mov->moof->TrackList, k);
                        if (traf->tfhd) {
                            GF_TrackBox *trak = gf_isom_get_track_from_id(mov->moov, traf->tfhd->trackID);
                            u32 j=0;
                            while ((traf->trex = (GF_TrackExtendsBox*)gf_list_enum(mov->moov->mvex->TrackExList, &j))) {
                                if (traf->trex->trackID == traf->tfhd->trackID) {
                                    if (!traf->trex->track) traf->trex->track = trak;
                                    break;
                                }
                                traf->trex = NULL;
                            }
                        }
                        //we should only parse senc/psec when no saiz/saio is present, otherwise we fetch the info directly
                        if (traf->trex && traf->trex->track && (traf->piff_sample_encryption || traf->sample_encryption)) {
                            GF_TrackBox *trak = GetTrackbyID(mov->moov, traf->tfhd->trackID);
                            e = senc_Parse(mov->movieFileMap->bs, trak, traf, traf->piff_sample_encryption ? (GF_SampleEncryptionBox *) traf->piff_sample_encryption : traf->sample_encryption);
                        }
                    }
                }
            } else if (mov->openMode==GF_ISOM_OPEN_CAT_FRAGMENTS) {
                mov->NextMoofNumber = mov->moof->mfhd->sequence_number+1;
                mov->moof = NULL;
                gf_isom_box_del(a);
            } else {
                /*merge all info*/
                e = MergeFragment((GF_MovieFragmentBox *)a, mov);
                gf_isom_box_del(a);
            }
            break;
#endif
        case GF_4CC('j','P',' ',' '):
        {
            GF_UnknownBox *box = (GF_UnknownBox*)a;
            u8 *c = (u8 *) box->data;
            if ((box->dataSize==4)
                    && (GF_4CC(c[0],c[1],c[2],c[3])==(u32)0x0D0A870A))
                mov->is_jp2 = 1;

            gf_isom_box_del(a);
        }
        break;

        case GF_ISOM_BOX_TYPE_PRFT:
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
            if (!(mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG)) {
                //keep the last one read
                if (mov->last_producer_ref_time)
                    gf_isom_box_del(a);
                else
                    mov->last_producer_ref_time = (GF_ProducerReferenceTimeBox *)a;
                break;
            }
#endif
        //fallthrough

        default:
            totSize += a->size;
            e = gf_list_add(mov->TopBoxes, a);
            break;
        }

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
        /*remember where we left, in case we append an entire number of movie fragments*/
        mov->current_top_box_start = gf_bs_get_position(mov->movieFileMap->bs);
#endif
    }

    /*we need at least moov or meta*/
    if (!mov->moov && !mov->meta
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
            && !mov->moof && !mov->is_index_segment
#endif
       ) {
        return GF_ISOM_INCOMPLETE_FILE;
    }
    /*we MUST have movie header*/
    if (mov->moov && !mov->moov->mvhd) {
        GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MVHD in MOOV!\n"));
        return GF_ISOM_INVALID_FILE;
    }
    /*we MUST have meta handler*/
    if (mov->meta && !mov->meta->handler) {
        GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing handler in META!\n"));
        return GF_ISOM_INVALID_FILE;
    }

#ifndef GPAC_DISABLE_ISOM_WRITE

    if (mov->moov) {
        /*set the default interleaving time*/
        mov->interleavingTime = mov->moov->mvhd->timeScale;

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
        /*in edit mode with successfully loaded fragments, delete all fragment signaling since
        file is no longer fragmented*/
        if ((mov->openMode > GF_ISOM_OPEN_READ) && (mov->openMode != GF_ISOM_OPEN_CAT_FRAGMENTS) && mov->moov->mvex) {
            gf_isom_box_del((GF_Box *)mov->moov->mvex);
            mov->moov->mvex = NULL;
        }
#endif

    }

    //create a default mdat if none was found
    if (!mov->mdat && (mov->openMode != GF_ISOM_OPEN_READ) && (mov->openMode != GF_ISOM_OPEN_CAT_FRAGMENTS)) {
        mov->mdat = (GF_MediaDataBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MDAT);
        e = gf_list_add(mov->TopBoxes, mov->mdat);
        if (e) return e;
    }
#endif /*GPAC_DISABLE_ISOM_WRITE*/

    return GF_OK;
}
示例#30
0
文件: main.c 项目: ARSekkat/gpac
int main(int argc, char **argv)
{
	/********************/
	/*   declarations   */
	/********************/
	char *input, *output, tmpstr[GF_MAX_PATH];
	GF_ISOFile *isom_file_in;
	GF_MediaImporter import;
	AdobeHDSCtx ctx;
	GF_Err e;
	u32 i;

	/*****************/
	/*   gpac init   */
	/*****************/
	gf_sys_init(GF_MemTrackerNone);
	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING);

	/***********************/
	/*   initialisations   */
	/***********************/
	input = NULL;
	output = NULL;
	isom_file_in = NULL;
	memset(&import, 0, sizeof(GF_MediaImporter));
	e = GF_OK;
	memset(&ctx, 0, sizeof(ctx));

	ctx.curr_time = 0;
	ctx.segnum = 1;

	/*********************************************/
	/*   parse arguments and build HDS context   */
	/*********************************************/
	if (GF_OK != parse_args(argc, argv, &input, &output, &ctx.curr_time, &ctx.segnum)) {
		usage(argv[0]);
		goto exit;
	}

	ctx.multirate_manifest = adobe_alloc_multirate_manifest(output);

#if 0 /*'moov' conversion tests*/
	{
		char metamoov64[GF_MAX_PATH];
		u32 metamoov64_len;
		unsigned char metamoov[GF_MAX_PATH];
		u32 metamoov_len=GF_MAX_PATH;
		FILE *f = gf_fopen("metamoov64"/*input*/, "rt");
		gf_fseek(f, 0, SEEK_END);
		metamoov64_len = (u32)gf_ftell(f);
		gf_fseek(f, 0, SEEK_SET);
		fread(metamoov64, metamoov64_len, 1, f);
		metamoov_len = gf_base64_decode(metamoov64, metamoov64_len, metamoov, metamoov_len);
		gf_fclose(f);
		f = gf_fopen("metamoov", "wb");
		fwrite(metamoov, metamoov_len, 1, f);
		gf_fclose(f);
		return 0;
	}
#endif

#if 0 /*'abst'conversion tests*/
	{
		char bootstrap64[GF_MAX_PATH];
		u32 bootstrap64_len;
		unsigned char bootstrap[GF_MAX_PATH];
		u32 bootstrap_len=GF_MAX_PATH;
		GF_AdobeBootstrapInfoBox *abst = (GF_AdobeBootstrapInfoBox *)abst_New();
		GF_BitStream *bs;
#if 1 //64
		FILE *f = gf_fopen("bootstrap64"/*input*/, "rt");
		gf_fseek(f, 0, SEEK_END);
		bootstrap64_len = (u32)gf_ftell(f);
		gf_fseek(f, 0, SEEK_SET);
		fread(bootstrap64, bootstrap64_len, 1, f);
		bootstrap_len = gf_base64_decode(bootstrap64, bootstrap64_len, bootstrap, bootstrap_len);
#else //binary bootstrap
		FILE *f = gf_fopen("bootstrap.bin"/*input*/, "rb");
		gf_fseek(f, 0, SEEK_END);
		bootstrap_len = (u32)gf_ftell(f);
		gf_fseek(f, 0, SEEK_SET);
		fread(bootstrap, bootstrap_len, 1, f);
#endif
		bs = gf_bs_new(bootstrap+8, bootstrap_len-8, GF_BITSTREAM_READ);
		abst->size = bootstrap[2]*256+bootstrap[3];
		assert(abst->size<GF_MAX_PATH);
		abst_Read((GF_Box*)abst, bs);
		gf_bs_del(bs);
		//then rewrite with just one 'afrt'
		memset(bootstrap, 0, bootstrap_len);
		bs = gf_bs_new(bootstrap, bootstrap_len, GF_BITSTREAM_WRITE);
		abst_Write((GF_Box*)abst, bs);
		bootstrap_len = (u32)gf_bs_get_position(bs);
		gf_bs_del(bs);
		gf_fclose(f);
		f = gf_fopen("bootstrap", "wt");
		bootstrap64_len = gf_base64_encode(bootstrap, bootstrap_len, bootstrap64, GF_MAX_PATH);
		fwrite(bootstrap64, bootstrap64_len, 1, f);
		fprintf(f, "\n\n");
		abst_dump((GF_Box*)abst, f);
		gf_fclose(f);
		abst_del((GF_Box*)abst);
		return 0;
	}
#endif

	/*****************/
	/*   main loop   */
	/*****************/
	import.trackID = 0;
	import.in_name = input;
	import.flags = GF_IMPORT_PROBE_ONLY;

	//create output or open when recovering from a saved state
	sprintf(tmpstr, "%s_import.mp4", input);
	isom_file_in = gf_isom_open(tmpstr, GF_ISOM_WRITE_EDIT, NULL);
	if (!isom_file_in) {
		fprintf(stderr, "Error opening output file %s: %s\n", tmpstr, gf_error_to_string(e));
		assert(0);
		goto exit;
	}
	import.dest = isom_file_in;

	//probe input
	e = gf_media_import(&import);
	if (e) {
		fprintf(stderr, "Error while importing input file %s: %s\n", input, gf_error_to_string(e));
		assert(0);
		goto exit;
	}

	//import input data
	import.flags = 0;
	for (i=0; i<import.nb_tracks; i++) {
		import.trackID = import.tk_info[i].track_num;
		e = gf_media_import(&import);
		if (e) {
			fprintf(stderr, "Error while importing track number %u, input file %s: %s\n", import.trackID, input, gf_error_to_string(e));
			assert(0);
			goto exit;
		}
	}

	//Adobe specific stuff
	e = adobize_segment(isom_file_in, &ctx);
	if (e) {
		fprintf(stderr, "Couldn't turn the ISOM fragmented file into an Adobe f4v segment: %s\n", gf_error_to_string(e));
		assert(0);
		goto exit;
	}

	//interleave data and remove imported file
	//FIXME: set multiple fragments:
	sprintf(tmpstr, "%s_HD_100_Seg%u-Frag1", output, ctx.segnum); //FIXME: "HD", "100" and fragnum: pass as arg
	//e = gf_media_fragment_file(isom_file_in, tmpstr, 1.0);
	e = gf_media_fragment_file(isom_file_in, tmpstr, 1.0+gf_isom_get_duration(isom_file_in)/gf_isom_get_timescale(isom_file_in));
	if (e) {
		fprintf(stderr, "Error while fragmenting file to output %s: %s\n", output, gf_error_to_string(e));
		assert(0);
		goto exit;
	}
	gf_isom_delete(isom_file_in);
	isom_file_in = NULL;

	e = adobe_gen_multirate_manifest(ctx.multirate_manifest, ctx.bootstrap, ctx.bootstrap_size);
	if (e) {
		fprintf(stderr, "Couldn't generate Adobe f4m manifest: %s\n", gf_error_to_string(e));
		assert(0);
		goto exit;
	}

exit:
	//delete intermediate mp4 file
	if (isom_file_in)
		gf_isom_delete(isom_file_in);

	if (ctx.multirate_manifest)
		adobe_free_multirate_manifest(ctx.multirate_manifest);

	if (ctx.bootstrap) {
		gf_free(ctx.bootstrap);
		//ctx.bootstrap = NULL;
		//ctx.bootstrap_size = 0;
	}

	gf_sys_close();

	return !e ? 0 : 1;
}