Ejemplo n.º 1
0
//this is useful to duplicate on the fly a descriptor (mainly for authoring purposes)
GF_EXPORT
GF_Err gf_odf_desc_copy(GF_Descriptor *inDesc, GF_Descriptor **outDesc)
{
	GF_Err e;
	char *desc;
	u32 size;

	//warning: here we get some data allocated
	e = gf_odf_desc_write(inDesc, &desc, &size);
	if (e) return e;
	e = gf_odf_desc_read(desc, size, outDesc);
	gf_free(desc);
	return e;
}
Ejemplo n.º 2
0
GF_EXPORT
char *gf_seng_get_base64_iod(GF_SceneEngine *seng)
{
	u32 size, size64;
    char *buffer, *buf64;
	u32 i=0;
	GF_StreamContext*sc = NULL;

	if (!seng->ctx->root_od) return NULL;

	while ((sc = (GF_StreamContext*)gf_list_enum(seng->ctx->streams, &i))) {
		if ((sc->streamType == GF_STREAM_SCENE) && (sc->objectType != GPAC_OTI_SCENE_DIMS))
			break;
	}
	if (!sc) return NULL;

    size = 0;
    gf_odf_desc_write((GF_Descriptor *) seng->ctx->root_od, &buffer, &size);
    buf64 = gf_malloc(size*2);
    size64 = gf_base64_encode( buffer, size, buf64, size*2);
    buf64[size64] = 0;
    gf_free(buffer);
	return buf64;
}
Ejemplo n.º 3
0
int sdp_generator(PNC_CallbackData *data, char *ip_dest, char *sdp_fmt)
{
	GF_SceneEngine *codec;
	GF_ESD *esd = NULL;
	u32 size,size64;
	char *buffer;
	char buf64[5000];
	FILE *fp;
	int ret;
	char temp[5000];
	u16 port;
	u32 socket_type;
		
	gf_sk_get_local_info(data->chan->rtp, &port, &socket_type);

	fp = fopen("broadcaster.sdp", "w+");
	if(fp == NULL) {
		fprintf(stderr, "Cannot open SDP file broadcaster.sdp\n");
		exit(1);
	}

	ret = fwrite("v=0\n", 1, 4, fp);
	sprintf(temp, "o=GpacBroadcaster 3326096807 1117107880000 IN IP%d %s\n", gf_net_is_ipv6(ip_dest) ? 6 : 4, ip_dest);
	ret = fwrite(temp, 1, strlen(temp), fp);

	ret = fwrite("s=MPEG4Broadcaster\n", 1, 19, fp);
	
	sprintf(temp, "c=IN IP%d %s\n", gf_net_is_ipv6(ip_dest) ? 6 : 4, ip_dest);
	ret = fwrite(temp, 1, strlen(temp), fp);
	
	ret = fwrite("t=0 0\n", 1, 6, fp);
	
	codec = (GF_SceneEngine *) data->codec;
	if (codec) {
		buffer = NULL;
		size = 0;
		gf_odf_desc_write((GF_Descriptor *) codec->ctx->root_od, &buffer, &size);
		esd = gf_list_get(codec->ctx->root_od->ESDescriptors, 0);
	
		size64 = gf_base64_encode((unsigned char *) buffer, size, (unsigned char *) buf64, 2000);
		buf64[size64] = 0;
		free(buffer);

		sprintf(temp, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"\n", buf64);
		ret = fwrite(temp, 1, strlen(temp), fp);
	}
	
	sprintf(temp, "m=application %d RTP/AVP 96\n", port);
	ret = fwrite(temp, 1, strlen(temp), fp);
	
	ret = fwrite("a=rtpmap:96 mpeg4-generic/1000\n", 1, 31, fp);

	if (esd) {
		sprintf(temp, "a=mpeg4-esid:%d\n", esd->ESID);
		ret = fwrite(temp, 1, strlen(temp), fp);
	}
	
	sprintf(temp, "%s\n", sdp_fmt);
	ret = fwrite(temp, 1, strlen(temp), fp);
	fflush(fp);
	fclose(fp);
	dprintf(DEBUG_sdp_generator, "SDP file generated in broadcaster.sdp\n");
	return GF_OK;
}
Ejemplo n.º 4
0
GF_EXPORT
GF_Err gf_hinter_finalize(GF_ISOFile *file, u32 IOD_Profile, u32 bandwidth)
{
	u32 i, sceneT, odT, descIndex, size, size64;
	GF_InitialObjectDescriptor *iod;
	GF_SLConfig slc;
	GF_ESD *esd;
	GF_ISOSample *samp;
	Bool remove_ocr;
	char *buffer;
	char buf64[5000], sdpLine[2300];


	gf_isom_sdp_clean(file);

	if (bandwidth) {
		sprintf(buf64, "b=AS:%d", bandwidth);
		gf_isom_sdp_add_line(file, buf64);
	}
	//xtended attribute for copyright
	sprintf(buf64, "a=x-copyright: %s", "MP4/3GP File hinted with GPAC " GPAC_FULL_VERSION " (C)2000-2005 - http://gpac.sourceforge.net");
	gf_isom_sdp_add_line(file, buf64);

	if (IOD_Profile == GF_SDP_IOD_NONE) return GF_OK;

	odT = sceneT = 0;
	for (i=0; i<gf_isom_get_track_count(file); i++) {
		if (!gf_isom_is_track_in_root_od(file, i+1)) continue;
		switch (gf_isom_get_media_type(file,i+1)) {
		case GF_ISOM_MEDIA_OD:
			odT = i+1;
			break;
		case GF_ISOM_MEDIA_SCENE:
			sceneT = i+1;
			break;
		}
	}
	remove_ocr = 0;
	if (IOD_Profile == GF_SDP_IOD_ISMA_STRICT) {
		IOD_Profile = GF_SDP_IOD_ISMA;
		remove_ocr = 1;
	}

	/*if we want ISMA like iods, we need at least BIFS */
	if ( (IOD_Profile == GF_SDP_IOD_ISMA) && !sceneT ) return GF_BAD_PARAM;

	/*do NOT change PLs, we assume they are correct*/
	iod = (GF_InitialObjectDescriptor *) gf_isom_get_root_od(file);
	if (!iod) return GF_NOT_SUPPORTED;

	/*rewrite an IOD with good SL config - embbed data if possible*/
	if (IOD_Profile == GF_SDP_IOD_ISMA) {
		Bool is_ok = 1;
		while (gf_list_count(iod->ESDescriptors)) {
			esd = (GF_ESD*)gf_list_get(iod->ESDescriptors, 0);
			gf_odf_desc_del((GF_Descriptor *) esd);
			gf_list_rem(iod->ESDescriptors, 0);
		}


		/*get OD esd, and embbed stream data if possible*/
		if (odT) {
			esd = gf_isom_get_esd(file, odT, 1);
			if (gf_isom_get_sample_count(file, odT)==1) {
				samp = gf_isom_get_sample(file, odT, 1, &descIndex);
				if (gf_hinter_can_embbed_data(samp->data, samp->dataLength, GF_STREAM_OD)) {
					InitSL_NULL(&slc);
					slc.predefined = 0;
					slc.hasRandomAccessUnitsOnlyFlag = 1;
					slc.timeScale = slc.timestampResolution = gf_isom_get_media_timescale(file, odT);	
					slc.OCRResolution = 1000;
					slc.startCTS = samp->DTS+samp->CTS_Offset;
					slc.startDTS = samp->DTS;
					//set the SL for future extraction
					gf_isom_set_extraction_slc(file, odT, 1, &slc);

					size64 = gf_base64_encode(samp->data, samp->dataLength, buf64, 2000);
					buf64[size64] = 0;
					sprintf(sdpLine, "data:application/mpeg4-od-au;base64,%s", buf64);

					esd->decoderConfig->avgBitrate = 0;
					esd->decoderConfig->bufferSizeDB = samp->dataLength;
					esd->decoderConfig->maxBitrate = 0;
					size64 = strlen(sdpLine)+1;
					esd->URLString = (char*)gf_malloc(sizeof(char) * size64);
					strcpy(esd->URLString, sdpLine);
				} else {
					GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[rtp hinter] OD sample too large to be embedded in IOD - ISMA disabled\n"));
					is_ok = 0;
				}
				gf_isom_sample_del(&samp);
			}
			if (remove_ocr) esd->OCRESID = 0;
			else if (esd->OCRESID == esd->ESID) esd->OCRESID = 0;
			
			//OK, add this to our IOD
			gf_list_add(iod->ESDescriptors, esd);
		}

		esd = gf_isom_get_esd(file, sceneT, 1);
		if (gf_isom_get_sample_count(file, sceneT)==1) {
			samp = gf_isom_get_sample(file, sceneT, 1, &descIndex);
			if (gf_hinter_can_embbed_data(samp->data, samp->dataLength, GF_STREAM_SCENE)) {

				slc.timeScale = slc.timestampResolution = gf_isom_get_media_timescale(file, sceneT);	
				slc.OCRResolution = 1000;
				slc.startCTS = samp->DTS+samp->CTS_Offset;
				slc.startDTS = samp->DTS;
				//set the SL for future extraction
				gf_isom_set_extraction_slc(file, sceneT, 1, &slc);
				//encode in Base64 the sample
				size64 = gf_base64_encode(samp->data, samp->dataLength, buf64, 2000);
				buf64[size64] = 0;
				sprintf(sdpLine, "data:application/mpeg4-bifs-au;base64,%s", buf64);

				esd->decoderConfig->avgBitrate = 0;
				esd->decoderConfig->bufferSizeDB = samp->dataLength;
				esd->decoderConfig->maxBitrate = 0;
				esd->URLString = (char*)gf_malloc(sizeof(char) * (strlen(sdpLine)+1));
				strcpy(esd->URLString, sdpLine);
			} else {
				GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[rtp hinter] Scene description sample too large to be embedded in IOD - ISMA disabled\n"));
				is_ok = 0;
			}
			gf_isom_sample_del(&samp);
		}
		if (remove_ocr) esd->OCRESID = 0;
		else if (esd->OCRESID == esd->ESID) esd->OCRESID = 0;

		gf_list_add(iod->ESDescriptors, esd);

		if (is_ok) {
			u32 has_a, has_v, has_i_a, has_i_v;
			has_a = has_v = has_i_a = has_i_v = 0;
			for (i=0; i<gf_isom_get_track_count(file); i++) {
				esd = gf_isom_get_esd(file, i+1, 1);
				if (!esd) continue;
				if (esd->decoderConfig->streamType==GF_STREAM_VISUAL) {
					if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) has_i_v ++;
					else has_v++;
				} else if (esd->decoderConfig->streamType==GF_STREAM_AUDIO) {
					if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_AUDIO_AAC_MPEG4) has_i_a ++;
					else has_a++;
				}
				gf_odf_desc_del((GF_Descriptor *)esd);
			}
			/*only 1 MPEG-4 visual max and 1 MPEG-4 audio max for ISMA compliancy*/
			if (!has_v && !has_a && (has_i_v<=1) && (has_i_a<=1)) {
				sprintf(sdpLine, "a=isma-compliance:1,1.0,1");
				gf_isom_sdp_add_line(file, sdpLine);
			}
		}
	}

	//encode the IOD
	buffer = NULL;
	size = 0;
	gf_odf_desc_write((GF_Descriptor *) iod, &buffer, &size);
	gf_odf_desc_del((GF_Descriptor *)iod);

	//encode in Base64 the iod
	size64 = gf_base64_encode(buffer, size, buf64, 2000);
	buf64[size64] = 0;
	gf_free(buffer);

	sprintf(sdpLine, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"", buf64);
	gf_isom_sdp_add_line(file, sdpLine);

	return GF_OK;
}
Ejemplo n.º 5
0
int sdp_generator(PNC_CallbackData * data, char *ip_dest, char *sdp_fmt)
{
	GF_BifsEngine *codec;
	GF_ESD *esd;
	u32 size,size64;
	char *buffer;
	char buf64[5000];
	FILE *fp;
	int ret;
	char temp[5000];
	u16 port;
	u32 socket_type;
		
	// fonctions necessaires pour recuperer les informations necessaires a la construction du fichier
	gf_sk_get_local_info(data->chan->rtp, &port, &socket_type);

	// fprintf(stdout, "%s --------- %d\n", ip_adresse, port);
	fp = fopen("broadcaster.sdp", "w+");
	if(fp == NULL)
	{
		fprintf(stdout, "[broadcaster] : erreur, probleme a ouvrir file temp pour scene initiale\n");
		exit(1);
	}
	// ecriture du fichier SDP
	ret = fwrite("v=0\n", 1, 4, fp);
	
	sprintf(temp, "o=GpacBroadcaster 3326096807 1117107880000 IN IP%d %s\n", gf_net_is_ipv6(ip_dest) ? 6 : 4, ip_dest);
	ret = fwrite(temp, 1, strlen(temp), fp);
	
	ret = fwrite("s=MPEG4Broadcaster\n", 1, 19, fp);
	
	sprintf(temp, "c=IN IP%d %s\n", gf_net_is_ipv6(ip_dest) ? 6 : 4, ip_dest);
	ret = fwrite(temp, 1, strlen(temp), fp);
	
	ret = fwrite("t=0 0\n", 1, 6, fp);
	
	// GF_BIFSEngine
	codec = (GF_BifsEngine *) data->codec;
	buffer = NULL;
	size = 0;
	gf_odf_desc_write((GF_Descriptor *) codec->ctx->root_od, &buffer, &size);
	esd = gf_list_get(codec->ctx->root_od->ESDescriptors, 0);
	
	//encode in Base64 the iod
	size64 = gf_base64_encode((unsigned char *) buffer, size, (unsigned char *) buf64, 2000);
	// size64 = gf_base64_encode(buffer, size, buf64, 2000);
	buf64[size64] = 0;
	free(buffer);

	// fprintf(stdout, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"\n", buf64);
	sprintf(temp, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"\n", buf64);
	ret = fwrite(temp, 1, strlen(temp), fp);
	
	sprintf(temp, "m=application %d RTP/AVP 96\n", port);
	ret = fwrite(temp, 1, strlen(temp), fp);
	
	ret = fwrite("a=rtpmap:96 mpeg4-generic/1000\n", 1, 31, fp);

	sprintf(temp, "a=mpeg4-esid:%d\n", esd->ESID);
	ret = fwrite(temp, 1, strlen(temp), fp);
	
	// fprintf(stdout, "%s\n", sdp_fmt);
	sprintf(temp, "%s\n", sdp_fmt);
	ret = fwrite(temp, 1, strlen(temp), fp);
	
	fclose(fp);
	fprintf(stdout, "[sdp generator] : fichier SDP generater in broadcaster.sdp\n");
	return GF_OK;
}