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

📄 isom_hinter.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / Media Tools sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/media_tools.h>#include <gpac/base_coding.h>#include <gpac/mpeg4_odf.h>#include <gpac/constants.h>#include <gpac/math.h>#include <gpac/ietf.h>#ifndef GPAC_READ_ONLY/*RTP track hinter*/struct __tag_isom_hinter{	GF_ISOFile *file;	/*IDs are kept for mp4 hint sample building*/	u32 TrackNum, TrackID, HintTrack, HintID;	/*current Hint sample and associated RTP time*/	u32 HintSample, RTPTime;	/*track has composition time offset*/	Bool has_ctts;	/*remember if first SL packet in RTP packet is RAP*/	u8 SampleIsRAP;	u32 base_offset_in_sample;	u32 OrigTimeScale;	/*rtp builder*/	GP_RTPPacketizer *rtp_p;	u32 bandwidth, nb_chan;	/*NALU size for H264/AVC*/	u32 avc_nalu_size;	/*stats*/	u32 TotalSample, CurrentSample;};/*	offset for group ID for hint tracks in SimpleAV mode when all media data	is copied to the hint track (no use interleaving hint and original in this case)	this offset is applied internally by the track hinter. Thus you shouldn't	specify a GroupID >= OFFSET_HINT_GROUP_ID if you want the lib to perform efficient	interleaving in any cases (referenced or copied media)*/#define OFFSET_HINT_GROUP_ID	0x8000void MP4T_DumpSDP(GF_ISOFile *file, const char *name){	const char *sdp;	u32 size, i;	FILE *f;	f = fopen(name, "wt");	//get the movie SDP	gf_isom_sdp_get(file, &sdp, &size);	fwrite(sdp, size, 1, f);	fprintf(f, "\r\n");	//then tracks	for (i=0; i<gf_isom_get_track_count(file); i++) {		if (gf_isom_get_media_type(file, i+1) != GF_ISOM_MEDIA_HINT) continue;		gf_isom_sdp_track_get(file, i+1, &sdp, &size);		fwrite(sdp, size, 1, f);	}	fclose(f);}/*out-of-band sample desc (128 and 255 reserved in RFC)*/#define SIDX_OFFSET_3GPP		129void GetAvgSampleInfos(GF_ISOFile *file, u32 Track, u32 *avgSize, u32 *MaxSize, u32 *TimeDelta, u32 *maxCTSDelta, u32 *const_duration, u32 *bandwidth){	u32 i, count, ts_diff;	u64 prevTS, DTS, tdelta;	Double bw;	GF_ISOSample *samp;	*avgSize = *MaxSize = 0;	*TimeDelta = 0;	*maxCTSDelta = 0;	bw = 0;	prevTS = 0;	DTS = 0;	tdelta = 0;	count = gf_isom_get_sample_count(file, Track);	*const_duration = 0;	for (i=0; i<count; i++) {		samp = gf_isom_get_sample_info(file, Track, i+1, NULL, NULL);		//get the size		*avgSize += samp->dataLength;		if (*MaxSize < samp->dataLength) *MaxSize = samp->dataLength;		ts_diff = (u32) (samp->DTS+samp->CTS_Offset - prevTS);		//get the time		tdelta += ts_diff;		if (i==1) {			*const_duration = ts_diff;		} else if ( (i<count-1) && (*const_duration != ts_diff) ) {			*const_duration = 0;		}		prevTS = samp->DTS+samp->CTS_Offset;		bw += 8*samp->dataLength;				//get the CTS delta		if (samp->CTS_Offset > *maxCTSDelta) *maxCTSDelta = samp->CTS_Offset;		gf_isom_sample_del(&samp);	}	if (count>1) *TimeDelta = (u32) (tdelta/ (count-1) );	else *TimeDelta = (u32) tdelta;	*avgSize /= count;	bw *= gf_isom_get_media_timescale(file, Track);	bw /= (s64) gf_isom_get_media_duration(file, Track);	bw /= 1000;	(*bandwidth) = (u32) (bw+0.5);	//delta is NOT an average, we need to know exactly how many bits are	//needed to encode CTS-DTS for ANY samples}void InitSL_RTP(GF_SLConfig *slc){	memset(slc, 0, sizeof(GF_SLConfig));	slc->tag = GF_ODF_SLC_TAG;	slc->useTimestampsFlag = 1;	slc->timestampLength = 32;}void InitSL_NULL(GF_SLConfig *slc){	memset(slc, 0, sizeof(GF_SLConfig));	slc->tag = GF_ODF_SLC_TAG;	slc->predefined = 0x01;}void MP4T_OnPacketDone(void *cbk, GF_RTPHeader *header){	u8 disposable;	GF_RTPHinter *tkHint = (GF_RTPHinter *)cbk;	if (!tkHint || !tkHint->HintSample) return;	assert(header->TimeStamp == tkHint->RTPTime);		disposable = 0;	if (tkHint->avc_nalu_size) {		disposable = tkHint->rtp_p->avc_non_idr ? 1 : 0;	}	/*for all other, assume that CTS=DTS means B-frame -> disposable*/	else if (tkHint->has_ctts && (tkHint->rtp_p->sl_header.compositionTimeStamp==tkHint->rtp_p->sl_header.decodingTimeStamp)) {		disposable = 1;	}	gf_isom_rtp_packet_set_flags(tkHint->file, tkHint->HintTrack, 0, 0, header->Marker, disposable, 0);}void MP4T_OnDataRef(void *cbk, u32 payload_size, u32 offset_from_orig){	GF_RTPHinter *tkHint = (GF_RTPHinter *)cbk;	if (!tkHint || !payload_size) return;	/*add reference*/	gf_isom_hint_sample_data(tkHint->file, tkHint->HintTrack, tkHint->TrackID,			tkHint->CurrentSample, (u16) payload_size, offset_from_orig + tkHint->base_offset_in_sample, 			NULL, 0);}void MP4T_OnData(void *cbk, char *data, u32 data_size, Bool is_header){	u8 at_begin;	GF_RTPHinter *tkHint = (GF_RTPHinter *)cbk;	if (!data_size) return;	at_begin = is_header ? 1 : 0;	if (data_size <= 14) {		gf_isom_hint_direct_data(tkHint->file, tkHint->HintTrack, data, data_size, at_begin);	} else {		gf_isom_hint_sample_data(tkHint->file, tkHint->HintTrack, tkHint->HintID, 0, (u16) data_size, 0, data, at_begin);	}}void MP4T_OnNewPacket(void *cbk, GF_RTPHeader *header){	s32 res;	GF_RTPHinter *tkHint = (GF_RTPHinter *)cbk;	if (!tkHint) return;	res = (s32) (tkHint->rtp_p->sl_header.compositionTimeStamp - tkHint->rtp_p->sl_header.decodingTimeStamp);	assert( !res || tkHint->has_ctts);	/*do we need a new sample*/	if (!tkHint->HintSample || (tkHint->RTPTime != header->TimeStamp)) {		/*close current sample*/		if (tkHint->HintSample) gf_isom_end_hint_sample(tkHint->file, tkHint->HintTrack, tkHint->SampleIsRAP);		/*start new sample: We use DTS as the sampling instant (RTP TS) to make sure		all packets are sent in order*/		gf_isom_begin_hint_sample(tkHint->file, tkHint->HintTrack, 1, header->TimeStamp-res);		tkHint->HintSample ++;		tkHint->RTPTime = header->TimeStamp;		tkHint->SampleIsRAP = tkHint->rtp_p->sl_config.hasRandomAccessUnitsOnlyFlag ? 1 : tkHint->rtp_p->sl_header.randomAccessPointFlag;	}	/*create an RTP Packet with the appropriated marker flag - note: the flags are temp ones, 	they are set when the full packet is signaled (to handle multi AUs per RTP)*/	gf_isom_rtp_packet_begin(tkHint->file, tkHint->HintTrack, 0, 0, 0, header->Marker, header->PayloadType, 0, 0, header->SequenceNumber);	/*Add the delta TS to make sure RTP TS is indeed the CTS (sampling time)*/	if (res) gf_isom_rtp_packet_set_offset(tkHint->file, tkHint->HintTrack, res);}GP_RTPPacketizer *gf_rtp_packetizer_create_and_init_from_file(GF_ISOFile *file, 															  u32 TrackNum,															  void *cbk_obj, 															  void (*OnNewPacket)(void *cbk, GF_RTPHeader *header),															  void (*OnPacketDone)(void *cbk, GF_RTPHeader *header),															  void (*OnDataReference)(void *cbk, u32 payload_size, u32 offset_from_orig),															  void (*OnData)(void *cbk, char *data, u32 data_size, Bool is_head),															  u32 Path_MTU, 															  u32 max_ptime, 															  u32 default_rtp_rate, 															  u32 flags, 															  u8 PayloadID, 															  Bool copy_media, 															  u32 InterleaveGroupID, 															  u8 InterleaveGroupPriority){	GF_SLConfig my_sl;	u32 MinSize, MaxSize, avgTS, streamType, oti, const_dur, nb_ch, maxDTSDelta;	u8 OfficialPayloadID;	u32 TrackMediaSubType, TrackMediaType, hintType, required_rate, force_dts_delta, avc_nalu_size, PL_ID, bandwidth, IV_length, KI_length;	const char *url, *urn;	char *mpeg4mode;	Bool is_crypted, has_mpeg4_mapping;	GF_ESD *esd;	GP_RTPPacketizer *rtp_packetizer = NULL;		/*by default NO PL signaled*/	PL_ID = 0;	OfficialPayloadID = 0;	force_dts_delta = 0;	streamType = oti = 0;	mpeg4mode = NULL;	required_rate = 0;	is_crypted = 0;	IV_length = KI_length = 0;	oti = 0;	nb_ch = 0;	avc_nalu_size = 0;	has_mpeg4_mapping = 1;	TrackMediaType = gf_isom_get_media_type(file, TrackNum);	TrackMediaSubType = gf_isom_get_media_subtype(file, TrackNum, 1);		/*for max compatibility with QT*/	if (!default_rtp_rate) default_rtp_rate = 90000;	/*timed-text is a bit special, we support multiple stream descriptions & co*/	if (TrackMediaType==GF_ISOM_MEDIA_TEXT) {		hintType = GF_RTP_PAYT_3GPP_TEXT;		oti = 0x08;		streamType = GF_STREAM_TEXT;		/*fixme - this works cos there's only one PL for text in mpeg4 at the current time*/		PL_ID = 0x10;	} else {		if (gf_isom_get_sample_description_count(file, TrackNum) > 1) return NULL;		TrackMediaSubType = gf_isom_get_media_subtype(file, TrackNum, 1);		switch (TrackMediaSubType) {		case GF_ISOM_SUBTYPE_MPEG4_CRYP: 			is_crypted = 1;		case GF_ISOM_SUBTYPE_MPEG4:			esd = gf_isom_get_esd(file, TrackNum, 1);			hintType = GF_RTP_PAYT_MPEG4;			if (esd) {				streamType = esd->decoderConfig->streamType;				oti = esd->decoderConfig->objectTypeIndication;				if (esd->URLString) hintType = 0;				/*AAC*/				if ((streamType==GF_STREAM_AUDIO) && esd->decoderConfig->decoderSpecificInfo				/*(nb: we use mpeg4 for MPEG-2 AAC)*/				&& ((oti==0x40) || (oti==0x40) || (oti==0x66) || (oti==0x67) || (oti==0x68)) ) {					u32 sample_rate;					GF_M4ADecSpecInfo a_cfg;					gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg);					nb_ch = a_cfg.nb_chan;					sample_rate = a_cfg.base_sr;					PL_ID = a_cfg.audioPL;					switch (a_cfg.base_object_type) {					case GF_M4A_AAC_MAIN:					case GF_M4A_AAC_LC:						if (flags & GP_RTP_PCK_USE_LATM_AAC) {							hintType = GF_RTP_PAYT_LATM;							break;						}					case GF_M4A_AAC_SBR:					case GF_M4A_AAC_LTP:					case GF_M4A_AAC_SCALABLE:					case GF_M4A_ER_AAC_LC:					case GF_M4A_ER_AAC_LTP:					case GF_M4A_ER_AAC_SCALABLE:						mpeg4mode = "AAC";						break;					case GF_M4A_CELP:					case GF_M4A_ER_CELP:						mpeg4mode = "CELP";						break;					}					required_rate = sample_rate;				}				/*MPEG1/2 audio*/				else if ((streamType==GF_STREAM_AUDIO) && ((oti==0x69) || (oti==0x6B))) {					u32 sample_rate;					if (!is_crypted) {						GF_ISOSample *samp = gf_isom_get_sample(file, TrackNum, 1, NULL);						u32 hdr = GF_4CC((u8)samp->data[0], (u8)samp->data[1], (u8)samp->data[2], (u8)samp->data[3]);						nb_ch = gf_mp3_num_channels(hdr);						sample_rate = gf_mp3_sampling_rate(hdr);						gf_isom_sample_del(&samp);						hintType = GF_RTP_PAYT_MPEG12_AUDIO;						/*use official RTP/AVP payload type*/						OfficialPayloadID = 14;						required_rate = 90000;					}					/*encrypted MP3 must be sent through MPEG-4 generic to signal all ISMACryp stuff*/					else {						u8 bps;						gf_isom_get_audio_info(file, TrackNum, 1, &sample_rate, &nb_ch, &bps);						required_rate = sample_rate;					}				}				/*QCELP audio*/				else if ((streamType==GF_STREAM_AUDIO) && (oti==0xE1)) {					hintType = GF_RTP_PAYT_QCELP;

⌨️ 快捷键说明

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