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

📄 isom_hinter.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
				else if (gf_isom_has_sync_shadows(file, TrackNum) || gf_isom_has_sample_dependency(file, TrackNum)) {					flags |= GP_RTP_PCK_AUTO_CAROUSEL;				}				gf_odf_desc_del((GF_Descriptor*)esd);			}			break;		case GF_ISOM_SUBTYPE_3GP_H263:			hintType = GF_RTP_PAYT_H263;			required_rate = 90000;			streamType = GF_STREAM_VISUAL;			OfficialPayloadID = 34;			/*not 100% compliant (short header is missing) but should still work*/			oti = 0x20;			PL_ID = 0x01;			break;		case GF_ISOM_SUBTYPE_3GP_AMR:			required_rate = 8000;			hintType = GF_RTP_PAYT_AMR;			streamType = GF_STREAM_AUDIO;			has_mpeg4_mapping = 0;			nb_ch = 1;			break;		case GF_ISOM_SUBTYPE_3GP_AMR_WB:			required_rate = 16000;			hintType = GF_RTP_PAYT_AMR_WB;			streamType = GF_STREAM_AUDIO;			has_mpeg4_mapping = 0;			nb_ch = 1;			break;		case GF_ISOM_SUBTYPE_AVC_H264:		{			GF_AVCConfig *avcc = gf_isom_avc_config_get(file, TrackNum, 1);			required_rate = 90000;	/* "90 kHz clock rate MUST be used"*/			hintType = GF_RTP_PAYT_H264_AVC;			streamType = GF_STREAM_VISUAL;			avc_nalu_size = avcc->nal_unit_size;			oti = 0x21;			PL_ID = 0x0F;			gf_odf_avc_cfg_del(avcc);		}			break;		case GF_ISOM_SUBTYPE_3GP_QCELP:			required_rate = 8000;			hintType = GF_RTP_PAYT_QCELP;			streamType = GF_STREAM_AUDIO;			oti = 0xE1;			OfficialPayloadID = 12;			nb_ch = 1;			break;		case GF_ISOM_SUBTYPE_3GP_EVRC:		case GF_ISOM_SUBTYPE_3GP_SMV:			required_rate = 8000;			hintType = GF_RTP_PAYT_EVRC_SMV;			streamType = GF_STREAM_AUDIO;			oti = (TrackMediaSubType==GF_ISOM_SUBTYPE_3GP_EVRC) ? 0xA0 : 0xA1;			nb_ch = 1;			break;		default:			/*ERROR*/			hintType = 0;			break;		}	}	/*not hintable*/	if (!hintType) return NULL;	/*we only support self-contained files for hinting*/	gf_isom_get_data_reference(file, TrackNum, 1, &url, &urn);	if (url || urn) return NULL;		*e = GF_OUT_OF_MEM;	GF_SAFEALLOC(tmp, GF_RTPHinter);	if (!tmp) return NULL;	/*override hinter type if requested and possible*/	if (has_mpeg4_mapping && (flags & GP_RTP_PCK_FORCE_MPEG4)) {		hintType = GF_RTP_PAYT_MPEG4;		avc_nalu_size = 0;	}	/*use static payload ID if enabled*/	else if (OfficialPayloadID && (flags & GP_RTP_PCK_USE_STATIC_ID) ) {		PayloadID = OfficialPayloadID;	}	tmp->file = file;	tmp->TrackNum = TrackNum;	tmp->avc_nalu_size = avc_nalu_size;	tmp->nb_chan = nb_ch;	/*spatial scalability check*/	tmp->has_ctts = gf_isom_has_time_offset(file, TrackNum);	/*get sample info*/	GetAvgSampleInfos(file, TrackNum, &MinSize, &MaxSize, &avgTS, &maxDTSDelta, &const_dur, &bandwidth);	/*systems carousel: we need at least IDX and RAP signaling*/	if (flags & GP_RTP_PCK_AUTO_CAROUSEL) {		flags |= GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_SIGNAL_AU_IDX;	}	/*update flags in MultiSL*/	if (flags & GP_RTP_PCK_USE_MULTI) {		if (MinSize != MaxSize) flags |= GP_RTP_PCK_SIGNAL_SIZE;		if (!const_dur) flags |= GP_RTP_PCK_SIGNAL_TS;	}	if (tmp->has_ctts) flags |= GP_RTP_PCK_SIGNAL_TS;	/*default SL for RTP */	InitSL_RTP(&my_sl);	my_sl.timestampResolution = gf_isom_get_media_timescale(file, TrackNum);	/*override clockrate if set*/	if (required_rate) {		Double sc = required_rate;		sc /= my_sl.timestampResolution;		maxDTSDelta = (u32) (maxDTSDelta*sc);		my_sl.timestampResolution = required_rate;	}	/*switch to RTP TS*/	max_ptime = (u32) (max_ptime * my_sl.timestampResolution / 1000);	my_sl.AUSeqNumLength = gf_get_bit_size(gf_isom_get_sample_count(file, TrackNum));	my_sl.CUDuration = const_dur;	if (gf_isom_has_sync_points(file, TrackNum)) {		my_sl.useRandomAccessPointFlag = 1;	} else {		my_sl.useRandomAccessPointFlag = 0;		my_sl.hasRandomAccessUnitsOnlyFlag = 1;	}	if (is_crypted) {		Bool use_sel_enc;		gf_isom_get_ismacryp_info(file, TrackNum, 1, NULL, NULL, NULL, NULL, NULL, &use_sel_enc, &IV_length, &KI_length);		if (use_sel_enc) flags |= GP_RTP_PCK_SELECTIVE_ENCRYPTION;	}	// in case a different timescale was provided	tmp->OrigTimeScale = gf_isom_get_media_timescale(file, TrackNum);	tmp->rtp_p = gf_rtp_builder_new(hintType, &my_sl, flags, tmp, 								MP4T_OnNewPacket, MP4T_OnPacketDone, 								/*if copy, no data ref*/								copy_media ? NULL : MP4T_OnDataRef, 								MP4T_OnData);	//init the builder	gf_rtp_builder_init(tmp->rtp_p, PayloadID, Path_MTU, max_ptime,					   streamType, oti, PL_ID, MinSize, MaxSize, avgTS, maxDTSDelta, IV_length, KI_length, mpeg4mode);	/*ISMA compliance is a pain...*/	if (force_dts_delta) tmp->rtp_p->slMap.DTSDeltaLength = force_dts_delta;	/*		Hint Track Setup	*/	tmp->TrackID = gf_isom_get_track_id(file, TrackNum);	tmp->HintID = tmp->TrackID + 65535;	while (gf_isom_get_track_by_id(file, tmp->HintID)) tmp->HintID++;	tmp->HintTrack = gf_isom_new_track(file, tmp->HintID, GF_ISOM_MEDIA_HINT, my_sl.timestampResolution);	gf_isom_setup_hint_track(file, tmp->HintTrack, GF_ISOM_HINT_RTP);	/*create a hint description*/	gf_isom_new_hint_description(file, tmp->HintTrack, -1, -1, 0, &descIndex);	gf_isom_rtp_set_timescale(file, tmp->HintTrack, descIndex, my_sl.timestampResolution);	if (hintType==GF_RTP_PAYT_MPEG4) {		tmp->rtp_p->slMap.ObjectTypeIndication = oti;		/*set this SL for extraction.*/		gf_isom_set_extraction_slc(file, TrackNum, 1, &my_sl);	}	tmp->bandwidth = bandwidth;	/*set interleaving*/	gf_isom_set_track_group(file, TrackNum, InterleaveGroupID);	if (!copy_media) {		/*if we don't copy data set hint track and media track in the same group*/		gf_isom_set_track_group(file, tmp->HintTrack, InterleaveGroupID);	} else {		gf_isom_set_track_group(file, tmp->HintTrack, InterleaveGroupID + OFFSET_HINT_GROUP_ID);	}	/*use user-secified priority*/	InterleaveGroupPriority*=2;	gf_isom_set_track_priority_in_group(file, TrackNum, InterleaveGroupPriority+1);	gf_isom_set_track_priority_in_group(file, tmp->HintTrack, InterleaveGroupPriority);#if 0	/*QT FF: not setting these flags = server uses a random offset*/	gf_isom_rtp_set_time_offset(file, tmp->HintTrack, 1, 0);	/*we don't use seq offset for maintainance pruposes*/	gf_isom_rtp_set_time_sequence_offset(file, tmp->HintTrack, 1, 0);#endif	*e = GF_OK;	return tmp;}GF_EXPORTu32 gf_hinter_track_get_bandwidth(GF_RTPHinter *tkHinter){	return tkHinter->bandwidth;}GF_EXPORTu32 gf_hinter_track_get_flags(GF_RTPHinter *tkHinter){	return tkHinter->rtp_p->flags;}GF_EXPORTvoid gf_hinter_track_get_payload_name(GF_RTPHinter *tkHinter, char *payloadName){	char mediaName[30];	gf_rtp_builder_get_payload_name(tkHinter->rtp_p, payloadName, mediaName);}GF_EXPORTvoid gf_hinter_track_del(GF_RTPHinter *tkHinter){	if (!tkHinter) return;	if (tkHinter->rtp_p) gf_rtp_builder_del(tkHinter->rtp_p);	free(tkHinter);}GF_EXPORTGF_Err gf_hinter_track_process(GF_RTPHinter *tkHint){	u32 i, descIndex, duration;	u64 ts;	u8 PadBits;	Double ft;	GF_ISOSample *samp;	tkHint->HintSample = tkHint->RTPTime = 0;	tkHint->TotalSample = gf_isom_get_sample_count(tkHint->file, tkHint->TrackNum);	ft = tkHint->rtp_p->sl_config.timestampResolution;	ft /= tkHint->OrigTimeScale;	for (i=0; i<tkHint->TotalSample; i++) {		samp = gf_isom_get_sample(tkHint->file, tkHint->TrackNum, i+1, &descIndex);		if (!samp) return GF_IO_ERR;		//setup SL		tkHint->CurrentSample = i + 1;		/*keep same AU indicator if sync shadow - TODO FIXME: this assumes shadows are placed interleaved with 		the track content which is the case for GPAC scene carousel generation, but may not always be true*/		if (samp->IsRAP==2) {			tkHint->rtp_p->sl_header.AU_sequenceNumber -= 1;			samp->IsRAP = 1;		}		ts = (u64) (ft * (s64) (samp->DTS+samp->CTS_Offset));		tkHint->rtp_p->sl_header.compositionTimeStamp = ts;		ts = (u64) (ft * (s64)(samp->DTS));		tkHint->rtp_p->sl_header.decodingTimeStamp = ts;		tkHint->rtp_p->sl_header.randomAccessPointFlag = samp->IsRAP;		tkHint->base_offset_in_sample = 0;		/*crypted*/		if (tkHint->rtp_p->slMap.IV_length) {			GF_ISMASample *s = gf_isom_get_ismacryp_sample(tkHint->file, tkHint->TrackNum, samp, descIndex);			/*one byte take for selective_enc flag*/			if (s->flags & GF_ISOM_ISMA_USE_SEL_ENC) tkHint->base_offset_in_sample += 1;			if (s->flags & GF_ISOM_ISMA_IS_ENCRYPTED) tkHint->base_offset_in_sample += s->IV_length + s->KI_length;			free(samp->data);			samp->data = s->data;			samp->dataLength = s->dataLength;			gp_rtp_builder_set_cryp_info(tkHint->rtp_p, s->IV, (char*)s->key_indicator, (s->flags & GF_ISOM_ISMA_IS_ENCRYPTED) ? 1 : 0);			s->data = NULL;			s->dataLength = 0;			gf_isom_ismacryp_delete_sample(s);		}		if (tkHint->rtp_p->sl_config.usePaddingFlag) {			gf_isom_get_sample_padding_bits(tkHint->file, tkHint->TrackNum, i+1, &PadBits);			tkHint->rtp_p->sl_header.paddingBits = PadBits;		} else {			tkHint->rtp_p->sl_header.paddingBits = 0;		}				duration = gf_isom_get_sample_duration(tkHint->file, tkHint->TrackNum, i+1);		ts = (u32) (ft * (s64) (duration));		/*unpack nal units*/		if (tkHint->avc_nalu_size) {			u32 v, size;			u32 remain = samp->dataLength;			char *ptr = samp->data;			tkHint->rtp_p->sl_header.accessUnitStartFlag = 1;			tkHint->rtp_p->sl_header.accessUnitEndFlag = 0;			while (remain) {				size = 0;				v = tkHint->avc_nalu_size;				while (v) {					size |= (u8) *ptr;					ptr++;					remain--;					v-=1;					if (v) size<<=8;				}				tkHint->base_offset_in_sample = samp->dataLength-remain;				remain -= size;				tkHint->rtp_p->sl_header.accessUnitEndFlag = remain ? 0 : 1;				gf_rtp_builder_process(tkHint->rtp_p, ptr, size, (u8) !remain, samp->dataLength, duration, (u8) (descIndex + SIDX_OFFSET_3GPP) );				ptr += size;				tkHint->rtp_p->sl_header.accessUnitStartFlag = 0;			}		} else {			gf_rtp_builder_process(tkHint->rtp_p, samp->data, samp->dataLength, 1, samp->dataLength, duration, (u8) (descIndex + SIDX_OFFSET_3GPP) );		}		tkHint->rtp_p->sl_header.packetSequenceNumber += 1;		//signal some progress		gf_set_progress("Hinting", tkHint->CurrentSample, tkHint->TotalSample);		tkHint->rtp_p->sl_header.AU_sequenceNumber += 1;		gf_isom_sample_del(&samp);	}	//flush	gf_rtp_builder_process(tkHint->rtp_p, NULL, 0, 1, 0, 0, 0);	gf_isom_end_hint_sample(tkHint->file, tkHint->HintTrack, (u8) tkHint->SampleIsRAP);	return GF_OK;}void gf_hinter_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdpLine, GF_ISOFile *file, u32 track){	char buffer[2000];	u32 w, h, i, m_w, m_h;	s32 tx, ty;	s16 l;	sprintf(sdpLine, "a=fmtp:%d sver=60; ", builder->PayloadType);	gf_isom_get_track_layout_info(file, track, &w, &h, &tx, &ty, &l);	sprintf(buffer, "width=%d; height=%d; tx=%d; ty=%d; layer=%d; ", w, h, tx, ty, l);	strcat(sdpLine, buffer);	m_w = w;	m_h = h;	for (i=0; i<gf_isom_get_track_count(file); i++) {		switch (gf_isom_get_media_type(file, i+1)) {		case GF_ISOM_MEDIA_SCENE:		case GF_ISOM_MEDIA_VISUAL:			gf_isom_get_track_layout_info(file, i+1, &w, &h, &tx, &ty, &l);			if (w>m_w) m_w = w;			if (h>m_h) m_h = h;			break;		default:			break;		}	}	sprintf(buffer, "max-w=%d; max-h=%d", m_w, m_h);	strcat(sdpLine, buffer);	strcat(sdpLine, "; tx3g=");	for (i=0; i<gf_isom_get_sample_description_count(file, track); i++) {		char *tx3g;		u32 tx3g_len, len;		gf_isom_text_get_encoded_tx3g(file, track, i+1, SIDX_OFFSET_3GPP, &tx3g, &tx3g_len);		len = gf_base64_encode(tx3g, tx3g_len, buffer, 2000);

⌨️ 快捷键说明

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