⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isom_hinter.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
		free(tx3g);		buffer[len] = 0;		if (i) strcat(sdpLine, ", ");		strcat(sdpLine, buffer);	}}GF_EXPORTGF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo){	u32 Width, Height;	GF_DecoderConfig *dcd;	char sdpLine[20000];	char mediaName[30], payloadName[30];	Width = Height = 0;	gf_isom_sdp_clean_track(tkHint->file, tkHint->TrackNum);	if (gf_isom_get_media_type(tkHint->file, tkHint->TrackNum) == GF_ISOM_MEDIA_VISUAL)		gf_isom_get_visual_info(tkHint->file, tkHint->TrackNum, 1, &Width, &Height);	gf_rtp_builder_get_payload_name(tkHint->rtp_p, payloadName, mediaName);	/*TODO- extract out of rtp_p for future live tools*/	sprintf(sdpLine, "m=%s 0 RTP/%s %d", mediaName, tkHint->rtp_p->slMap.IV_length ? "SAVP" : "AVP", tkHint->rtp_p->PayloadType);	gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	if (tkHint->bandwidth) {		sprintf(sdpLine, "b=AS:%d", tkHint->bandwidth);		gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	}	if (tkHint->nb_chan) {		sprintf(sdpLine, "a=rtpmap:%d %s/%d/%d", tkHint->rtp_p->PayloadType, payloadName, tkHint->rtp_p->sl_config.timestampResolution, tkHint->nb_chan);	} else {		sprintf(sdpLine, "a=rtpmap:%d %s/%d", tkHint->rtp_p->PayloadType, payloadName, tkHint->rtp_p->sl_config.timestampResolution);	}	gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	/*control for MPEG-4*/	if (AddSystemInfo) {		sprintf(sdpLine, "a=mpeg4-esid:%d", gf_isom_get_track_id(tkHint->file, tkHint->TrackNum));		gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	}	/*control for QTSS/DSS*/	sprintf(sdpLine, "a=control:trackID=%d", gf_isom_get_track_id(tkHint->file, tkHint->HintTrack));	gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	/*H263 extensions*/	if (tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_H263) {		sprintf(sdpLine, "a=cliprect:0,0,%d,%d", Height, Width);		gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	}	/*AMR*/	else if ((tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_AMR) || (tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_AMR_WB)) {		sprintf(sdpLine, "a=fmtp:%d octet-align", tkHint->rtp_p->PayloadType);		gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	}	/*Text*/	else if (tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_3GPP_TEXT) {		gf_hinter_format_ttxt_sdp(tkHint->rtp_p, payloadName, sdpLine, tkHint->file, tkHint->TrackNum);		gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	}	/*EVRC/SMV in non header-free mode*/	else if ((tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_EVRC_SMV) && (tkHint->rtp_p->auh_size>1)) {		sprintf(sdpLine, "a=fmtp:%d maxptime=%d", tkHint->rtp_p->PayloadType, tkHint->rtp_p->auh_size*20);		gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	}	/*H264/AVC*/	else if (tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_H264_AVC) {		GF_AVCConfig *avcc = gf_isom_avc_config_get(tkHint->file, tkHint->TrackNum, 1);		sprintf(sdpLine, "a=fmtp:%d profile-level-id=%02X%02X%02X; packetization-mode=1", tkHint->rtp_p->PayloadType, avcc->AVCProfileIndication, avcc->profile_compatibility, avcc->AVCLevelIndication);		if (gf_list_count(avcc->pictureParameterSets) || gf_list_count(avcc->sequenceParameterSets)) {			u32 i, count, b64s;			char b64[200];			strcat(sdpLine, "; sprop-parameter-sets=");			count = gf_list_count(avcc->sequenceParameterSets);			for (i=0; i<count; i++) {				GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(avcc->sequenceParameterSets, i);				b64s = gf_base64_encode(sl->data, sl->size, b64, 200);				b64[b64s]=0;				strcat(sdpLine, b64);				if (i+1<count) strcat(sdpLine, ",");			}			if (i) strcat(sdpLine, ",");			count = gf_list_count(avcc->pictureParameterSets);			for (i=0; i<count; i++) {				GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(avcc->pictureParameterSets, i);				b64s = gf_base64_encode(sl->data, sl->size, b64, 200);				b64[b64s]=0;				strcat(sdpLine, b64);				if (i+1<count) strcat(sdpLine, ",");			}		}		gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);		gf_odf_avc_cfg_del(avcc);	}	/*MPEG-4 decoder config*/	else if (tkHint->rtp_p->rtp_payt==GF_RTP_PAYT_MPEG4) {		dcd = gf_isom_get_decoder_config(tkHint->file, tkHint->TrackNum, 1);		if (dcd && dcd->decoderSpecificInfo && dcd->decoderSpecificInfo->data) {			gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, sdpLine, dcd->decoderSpecificInfo->data, dcd->decoderSpecificInfo->dataLength);		} else {			gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, sdpLine, NULL, 0);		}		if (dcd) gf_odf_desc_del((GF_Descriptor *)dcd);		if (tkHint->rtp_p->slMap.IV_length) {			const char *kms;			gf_isom_get_ismacryp_info(tkHint->file, tkHint->TrackNum, 1, NULL, NULL, NULL, NULL, &kms, NULL, NULL, NULL);			if (!strnicmp(kms, "(key)", 5) || !strnicmp(kms, "(ipmp)", 6) || !strnicmp(kms, "(uri)", 5)) {				strcat(sdpLine, "; ISMACrypKey=");			} else {				strcat(sdpLine, "; ISMACrypKey=(uri)");			}			strcat(sdpLine, kms);		}		gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	}	/*MPEG-4 Audio LATM*/	else if (tkHint->rtp_p->rtp_payt==GF_RTP_PAYT_LATM) { 		GF_BitStream *bs; 		char *config_bytes; 		u32 config_size;  		/* form config string */ 		bs = gf_bs_new(NULL, 32, GF_BITSTREAM_WRITE); 		gf_bs_write_int(bs, 0, 1); /* AudioMuxVersion */ 		gf_bs_write_int(bs, 1, 1); /* all streams same time */ 		gf_bs_write_int(bs, 0, 6); /* numSubFrames */ 		gf_bs_write_int(bs, 0, 4); /* numPrograms */ 		gf_bs_write_int(bs, 0, 3); /* numLayer */  		/* audio-specific config */ 		dcd = gf_isom_get_decoder_config(tkHint->file, tkHint->TrackNum, 1); 		if (dcd) { 			gf_bs_write_data(bs, dcd->decoderSpecificInfo->data, dcd->decoderSpecificInfo->dataLength); 			gf_odf_desc_del((GF_Descriptor *)dcd); 		}  		/* other data */ 		gf_bs_write_int(bs, 0, 3); /* frameLengthType */ 		gf_bs_write_int(bs, 0xff, 8); /* latmBufferFullness */ 		gf_bs_write_int(bs, 0, 1); /* otherDataPresent */ 		gf_bs_write_int(bs, 0, 1); /* crcCheckPresent */ 		gf_bs_get_content(bs, &config_bytes, &config_size); 		gf_bs_del(bs);  		gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, sdpLine, config_bytes, config_size); 		gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); 		free(config_bytes); 	}	/*extensions for some mobile phones*/	if (Width && Height) {		sprintf(sdpLine, "a=framesize:%d %d-%d", tkHint->rtp_p->PayloadType, Width, Height);		gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine);	}	gf_isom_set_track_enabled(tkHint->file, tkHint->HintTrack, 1);	return GF_OK;}GF_EXPORTBool gf_hinter_can_embbed_data(char *data, u32 data_size, u32 streamType){	char data64[5000];	u32 size64;	size64 = gf_base64_encode(data, data_size, data64, 5000);	if (!size64) return 0;	switch (streamType) {	case GF_STREAM_OD:		size64 += strlen("data:application/mpeg4-od-au;base64,");		break;	case GF_STREAM_SCENE:		size64 += strlen("data:application/mpeg4-bifs-au;base64,");		break;	default:		/*NOT NORMATIVE*/		size64 += strlen("data:application/mpeg4-es-au;base64,");		break;	}	if (size64>=255) return 0;	return 1;}GF_EXPORTGF_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_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*)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*)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==0x20) has_i_v ++;					else has_v++;				} else if (esd->decoderConfig->streamType==GF_STREAM_AUDIO) {					if (esd->decoderConfig->objectTypeIndication==0x40) 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;	free(buffer);	sprintf(sdpLine, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"", buf64);	gf_isom_sdp_add_line(file, sdpLine);	return GF_OK;}#endif //GPAC_READ_ONLY

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -