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

📄 rtp_pck_mpeg4.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / IETF RTP/RTSP/SDP 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/internal/ietf_dev.h>#include <gpac/constants.h>//get the size of the RSLH section given the GF_SLHeader and the SLMapstatic u32 gf_rtp_build_au_hdr_size(GP_RTPPacketizer *builder, GF_SLHeader *slh){	u32 nbBits = 0;	/*sel enc*/	if (builder->flags & GP_RTP_PCK_SELECTIVE_ENCRYPTION) nbBits += 8;	/*Note: ISMACryp ALWAYS indicates IV (BSO) and KEYIDX, even when sample is not encrypted. This is	quite a waste when using selective encryption....*/	/*IV*/	nbBits += builder->first_sl_in_rtp ? 8*builder->slMap.IV_length : 8*builder->slMap.IV_delta_length;	/*keyIndicator*/	if (builder->first_sl_in_rtp || (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU)) {		nbBits += 8*builder->slMap.KI_length;	}	/*no input header specified, compute the MAX size*/	if (!slh) {		/*size length*/		if (!builder->slMap.ConstantSize) nbBits += builder->slMap.SizeLength;		/*AU index length*/		nbBits += builder->first_sl_in_rtp ? builder->slMap.IndexLength : builder->slMap.IndexDeltaLength;		/*CTS flag*/		if (builder->slMap.CTSDeltaLength) {			nbBits += 1;			/*all non-first packets have the CTS written if asked*/			if (!builder->first_sl_in_rtp) nbBits += builder->slMap.CTSDeltaLength;		}		if (builder->slMap.DTSDeltaLength) nbBits += 1 + builder->slMap.DTSDeltaLength;		if (builder->flags & GP_RTP_PCK_SELECTIVE_ENCRYPTION) nbBits += 8;		return nbBits;	}	/*size length*/	if (!builder->slMap.ConstantSize) nbBits += builder->slMap.SizeLength;	/*AU index*/	if (builder->first_sl_in_rtp) {		if (builder->slMap.IndexLength) nbBits += builder->slMap.IndexLength;	} else {		if (builder->slMap.IndexDeltaLength) nbBits += builder->slMap.IndexDeltaLength;	}	/*CTS Flag*/	if (builder->slMap.CTSDeltaLength) {		/*CTS not written if first SL*/		if (builder->first_sl_in_rtp) slh->compositionTimeStampFlag = 0;		/*but CTS flag is always written*/		nbBits += 1;	} else {		slh->compositionTimeStampFlag = 0;	}	/*CTS*/	if (slh->compositionTimeStampFlag) nbBits += builder->slMap.CTSDeltaLength;	/*DTS Flag*/	if (builder->slMap.DTSDeltaLength) {		nbBits += 1;	} else {		slh->decodingTimeStampFlag = 0;	}	/*DTS*/	if (slh->decodingTimeStampFlag) nbBits += builder->slMap.DTSDeltaLength;	/*RAP indication*/	if (builder->slMap.RandomAccessIndication) nbBits ++;	/*streamState indication*/	nbBits += builder->slMap.StreamStateIndication;	return nbBits;}/*write the AU header section - return the nb of BITS written for AU header*/u32 gf_rtp_build_au_hdr_write(GP_RTPPacketizer *builder, u32 PayloadSize, u32 RTP_TS){	u32 nbBits = 0;	s32 delta;		/*selective encryption*/	if (builder->flags & GP_RTP_PCK_SELECTIVE_ENCRYPTION) {		gf_bs_write_int(builder->pck_hdr, builder->is_encrypted, 1);		gf_bs_write_int(builder->pck_hdr, 0, 7);		nbBits = 8;	}	/*IV*/	if (builder->first_sl_in_rtp) {		if (builder->slMap.IV_length) {			gf_bs_write_long_int(builder->pck_hdr, builder->IV, 8*builder->slMap.IV_length);			nbBits += 8*builder->slMap.IV_length;		}	} else if (builder->slMap.IV_delta_length) {		/*NOT SUPPORTED!!! this only applies to interleaving*/	}	/*key*/	if (builder->slMap.KI_length) {		if (builder->first_sl_in_rtp || (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU)) {			if (builder->key_indicator) gf_bs_write_data(builder->pck_hdr, builder->key_indicator, builder->slMap.KI_length);			else gf_bs_write_int(builder->pck_hdr, 0, 8*builder->slMap.KI_length);			nbBits += 8*builder->slMap.KI_length;		}	}	/*size length*/	if (builder->slMap.ConstantSize) {		if (PayloadSize != builder->slMap.ConstantSize) return nbBits;	} else if (builder->slMap.SizeLength) {		/*write the AU size - if not enough bytes (real-time cases) set size to 0*/		if (builder->sl_header.accessUnitLength >= (1<<builder->slMap.SizeLength)) {			gf_bs_write_int(builder->pck_hdr, 0, builder->slMap.SizeLength);		} else {			gf_bs_write_int(builder->pck_hdr, builder->sl_header.accessUnitLength, builder->slMap.SizeLength);		}		nbBits += builder->slMap.SizeLength;	}	/*AU index*/	if (builder->first_sl_in_rtp) {		if (builder->slMap.IndexLength) {			gf_bs_write_int(builder->pck_hdr, builder->sl_header.AU_sequenceNumber, builder->slMap.IndexLength);			nbBits += builder->slMap.IndexLength;		}	} else {		if (builder->slMap.IndexDeltaLength) {			//check interleaving, otherwise force default (which is currently always the case)			delta = builder->sl_header.AU_sequenceNumber - builder->last_au_sn;			delta -= 1;			gf_bs_write_int(builder->pck_hdr, delta, builder->slMap.IndexDeltaLength);			nbBits += builder->slMap.IndexDeltaLength;		}	}	/*CTS Flag*/	if (builder->slMap.CTSDeltaLength) {		if (builder->first_sl_in_rtp) {			builder->sl_header.compositionTimeStampFlag = 0;			builder->sl_header.compositionTimeStamp = RTP_TS;		}		gf_bs_write_int(builder->pck_hdr, builder->sl_header.compositionTimeStampFlag, 1);		nbBits += 1;	}	/*CTS*/	if (builder->sl_header.compositionTimeStampFlag) {		delta = (u32) builder->sl_header.compositionTimeStamp - RTP_TS;		gf_bs_write_int(builder->pck_hdr, delta, builder->slMap.CTSDeltaLength);		nbBits += builder->slMap.CTSDeltaLength;	}	/*DTS Flag*/	if (builder->slMap.DTSDeltaLength) {		gf_bs_write_int(builder->pck_hdr, builder->sl_header.decodingTimeStampFlag, 1);		nbBits += 1;	}	/*DTS*/	if (builder->sl_header.decodingTimeStampFlag) {		delta = (u32) (builder->sl_header.compositionTimeStamp - builder->sl_header.decodingTimeStamp);		gf_bs_write_int(builder->pck_hdr, delta, builder->slMap.DTSDeltaLength);		nbBits += builder->slMap.DTSDeltaLength;	}	/*RAP indication*/	if (builder->slMap.RandomAccessIndication) {		gf_bs_write_int(builder->pck_hdr, builder->sl_header.randomAccessPointFlag, 1);		nbBits ++;	}	return nbBits;}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, rslh_tmp, bytesLeftInPacket, infoSize, pckSize, pos;	u8 flush_pck, no_split;	flush_pck = 0;	rslh_tmp = 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;		}

⌨️ 快捷键说明

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