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

📄 rtp_payloads.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / RTP input module * *  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 "rtp_in.h"#include <gpac/avparse.h>u32 payt_get_type(RTPClient *rtp, GF_RTPMap *map, GF_SDPMedia *media){	u32 i, j;	if (!stricmp(map->payload_name, "MP4V-ES") ) return GP_RTP_PAYT_MPEG4;	else if (!stricmp(map->payload_name, "mpeg4-generic")) return GP_RTP_PAYT_MPEG4;	else if (!stricmp(map->payload_name, "enc-mpeg4-generic")) return GP_RTP_PAYT_MPEG4;	/*optibase mm400 card hack*/	else if (!stricmp(map->payload_name, "enc-generic-mp4") ) {		free(map->payload_name);		map->payload_name = strdup("enc-mpeg4-generic");		return GP_RTP_PAYT_MPEG4;	}	/*LATM: only without multiplexing (not tested but should be straight AUs)*/	else if (!stricmp(map->payload_name, "MP4A-LATM")) {		GF_SDP_FMTP *fmtp;		i=0;		while ((fmtp = (GF_SDP_FMTP *) gf_list_enum(media->FMTP, &i))) {			GF_X_Attribute *att;			if (fmtp->PayloadType != map->PayloadType) continue;			//this is our payload. check cpresent is 0			j=0;			while ((att = (GF_X_Attribute *)gf_list_enum(fmtp->Attributes, &j))) {				if (!stricmp(att->Name, "cpresent") && atoi(att->Value)) return 0;			}		}		return GP_RTP_PAYT_LATM;	}	else if (!stricmp(map->payload_name, "MPA") || !stricmp(map->payload_name, "MPV")) return GP_RTP_PAYT_MPEG12;	else if (!stricmp(map->payload_name, "H263-1998") || !stricmp(map->payload_name, "H263-2000")) return GP_RTP_PAYT_H263;	else if (!stricmp(map->payload_name, "AMR")) return GP_RTP_PAYT_AMR;	else if (!stricmp(map->payload_name, "AMR-WB")) return GP_RTP_PAYT_AMR_WB;	else if (!stricmp(map->payload_name, "3gpp-tt")) return GP_RTP_PAYT_3GPP_TEXT;	else if (!stricmp(map->payload_name, "H264")) return GP_RTP_PAYT_H264_AVC;	else return 0;}static GF_Err payt_set_param(RTPStream *ch, char *param_name, char *param_val){	u32 i, val;	char valS[3];	GF_BitStream *bs;	if (!ch || !param_name) return GF_BAD_PARAM;	/*1 - mpeg4-generic / RFC 3016 payload type items*/	/*PL (not needed when IOD is here)*/	if (!stricmp(param_name, "Profile-level-id")) {		if (ch->rtptype==GP_RTP_PAYT_H264_AVC) {			sscanf(param_val, "%x", &ch->sl_map.PL_ID);		} else {			ch->sl_map.PL_ID = atoi(param_val);		}	}	/*decoder specific info (not needed when IOD is here)*/	else if (!stricmp(param_name, "config")) {		u32 len = strlen(param_val);		//decode the buffer - the string buffer is MSB hexadecimal		bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);		valS[2] = 0;		for (i=0; i<len;i+=2) {			valS[0] = param_val[i];			valS[1] = param_val[i+1];			sscanf(valS, "%x", &val);			gf_bs_write_u8(bs, val);		}		if (ch->sl_map.config) free(ch->sl_map.config);		ch->sl_map.config = NULL;		gf_bs_get_content(bs, &ch->sl_map.config, &ch->sl_map.configSize);		gf_bs_del(bs);	}	/*mpeg4-generic payload type items required*/		/*constant size (size of all AUs) */	else if (!stricmp(param_name, "ConstantSize")) {		ch->sl_map.ConstantSize = atoi(param_val);	}	/*constant size (size of all AUs) */	else if (!stricmp(param_name, "ConstantDuration")) {		ch->sl_map.ConstantDuration = atoi(param_val);	}	/*object type indication (not needed when IOD is here)*/	else if (!stricmp(param_name, "ObjectType")) {		ch->sl_map.ObjectTypeIndication = atoi(param_val);	}	else if (!stricmp(param_name, "StreamType")) ch->sl_map.StreamType = atoi(param_val);	else if (!stricmp(param_name, "mode")) {		strcpy(ch->sl_map.mode, param_val);		/*in case no IOD and no streamType/OTI in the file*/		if (!stricmp(param_val, "AAC-hbr") || !stricmp(param_val, "AAC-lbr") || !stricmp(param_val, "CELP-vbr") || !stricmp(param_val, "CELP-cbr")) {			ch->sl_map.StreamType = GF_STREAM_AUDIO;			ch->sl_map.ObjectTypeIndication = 0x40;		}	}	else if (!stricmp(param_name, "DTSDeltaLength")) ch->sl_map.DTSDeltaLength = atoi(param_val);	else if (!stricmp(param_name, "CTSDeltaLength")) ch->sl_map.CTSDeltaLength = atoi(param_val);	else if (!stricmp(param_name, "SizeLength")) ch->sl_map.SizeLength = atoi(param_val);	else if (!stricmp(param_name, "IndexLength")) ch->sl_map.IndexLength = atoi(param_val);	else if (!stricmp(param_name, "IndexDeltaLength")) ch->sl_map.IndexDeltaLength = atoi(param_val);	else if (!stricmp(param_name, "RandomAccessIndication")) ch->sl_map.RandomAccessIndication = atoi(param_val);	else if (!stricmp(param_name, "StreamStateIndication")) ch->sl_map.StreamStateIndication = atoi(param_val);	else if (!stricmp(param_name, "AuxiliaryDataSizeLength")) ch->sl_map.AuxiliaryDataSizeLength = atoi(param_val);	/*H264/AVC config - we only handle mode 0 and 1*/	else if (!stricmp(param_name, "packetization-mode")) ch->packetization_mode = 1;	/*AMR config*/	else if (!stricmp(param_name, "octet-align")) ch->flags |= RTP_AMR_ALIGN;	/*ISMACryp config*/	else if (!stricmp(param_name, "ISMACrypCryptoSuite")) {		if (!stricmp(param_val, "AES_CTR_128")) ch->isma_scheme = GF_4CC('i','A','E','C');		else ch->isma_scheme = 0;	}	else if (!stricmp(param_name, "ISMACrypSelectiveEncryption")) {		if (!stricmp(param_val, "1") || !stricmp(param_val, "true"))			ch->flags |= RTP_ISMA_SEL_ENC;		else			ch->flags &= ~RTP_ISMA_SEL_ENC;	}	else if (!stricmp(param_name, "ISMACrypIVLength")) ch->sl_map.IV_length = atoi(param_val);	else if (!stricmp(param_name, "ISMACrypDeltaIVLength")) ch->sl_map.IV_delta_length = atoi(param_val);	else if (!stricmp(param_name, "ISMACrypKeyIndicatorLength")) ch->sl_map.KI_length = atoi(param_val);	else if (!stricmp(param_name, "ISMACrypKeyIndicatorPerAU")) {		if (!stricmp(param_val, "1") || !stricmp(param_val, "true"))			ch->flags |= RTP_ISMA_HAS_KEY_IDX;		else 			ch->flags &= ~RTP_ISMA_HAS_KEY_IDX;	}	else if (!stricmp(param_name, "ISMACrypKey")) ch->key = strdup(param_val);			return GF_OK;}u32 payt_setup(RTPStream *ch, GF_RTPMap *map, GF_SDPMedia *media){	u32 i, j;	GF_SDP_FMTP *fmtp;	/*reset sl map*/	memset(&ch->sl_map, 0, sizeof(GP_RTPSLMap));		/*setup channel*/	gf_rtp_setup_payload(ch->rtp_ch, map);	if (!stricmp(map->payload_name, "enc-mpeg4-generic")) ch->flags |= RTP_HAS_ISMACRYP;	/*then process all FMTPs*/	i=0;	while ((fmtp = (GF_SDP_FMTP*)gf_list_enum(media->FMTP, &i))) {		GF_X_Attribute *att;		//we work with only one PayloadType for now		if (fmtp->PayloadType != map->PayloadType) continue;		j=0;		while ((att = (GF_X_Attribute *)gf_list_enum(fmtp->Attributes, &j))) {			payt_set_param(ch, att->Name, att->Value);		}	}	switch (ch->rtptype) {	case GP_RTP_PAYT_LATM:	{		u32 AudioMuxVersion, AllStreamsSameTime, numSubFrames, numPrograms, numLayers;		GF_M4ADecSpecInfo cfg;		char *latm_dsi = ch->sl_map.config;		GF_BitStream *bs = gf_bs_new(latm_dsi, ch->sl_map.configSize, GF_BITSTREAM_READ);		AudioMuxVersion = gf_bs_read_int(bs, 1);		AllStreamsSameTime = gf_bs_read_int(bs, 1);		numSubFrames = gf_bs_read_int(bs, 6);		numPrograms = gf_bs_read_int(bs, 4);		numLayers = gf_bs_read_int(bs, 3);		if (AudioMuxVersion || !AllStreamsSameTime || numSubFrames || numPrograms || numLayers) {			gf_bs_del(bs);			return 0;		}		memset(&cfg, 0, sizeof(cfg));		cfg.base_object_type = gf_bs_read_int(bs, 5);		cfg.base_sr_index = gf_bs_read_int(bs, 4);		if (cfg.base_sr_index == 0x0F) {			cfg.base_sr = gf_bs_read_int(bs, 24);		} else {			cfg.base_sr = GF_M4ASampleRates[cfg.base_sr_index];		}		cfg.nb_chan = gf_bs_read_int(bs, 4);		if (cfg.base_object_type==5) {			cfg.has_sbr = 1;			cfg.sbr_sr_index = gf_bs_read_int(bs, 4);			if (cfg.sbr_sr_index == 0x0F) {				cfg.sbr_sr = gf_bs_read_int(bs, 24);			} else {				cfg.sbr_sr = GF_M4ASampleRates[cfg.sbr_sr_index];			}			cfg.sbr_object_type = gf_bs_read_int(bs, 5);		}		gf_bs_del(bs);		free(ch->sl_map.config);		bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);		/*write as regular AAC*/		gf_bs_write_int(bs, cfg.base_object_type, 5);		gf_bs_write_int(bs, cfg.base_sr_index, 4);		gf_bs_write_int(bs, cfg.nb_chan, 4);		gf_bs_align(bs);		gf_bs_get_content(bs, &ch->sl_map.config, &ch->sl_map.configSize);		gf_bs_del(bs);		ch->sl_map.StreamType = GF_STREAM_AUDIO;		ch->sl_map.ObjectTypeIndication = 0x40;	}		break;	case GP_RTP_PAYT_MPEG4:		/*mark if AU header is present*/		ch->sl_map.auh_first_min_len = 0;		if (ch->flags & RTP_HAS_ISMACRYP) {			if (!ch->isma_scheme) ch->isma_scheme = GF_4CC('i','A','E','C');			if (!ch->sl_map.IV_length) ch->sl_map.IV_length = 4;			if (ch->flags & RTP_ISMA_SEL_ENC) ch->sl_map.auh_first_min_len += 8;			else ch->sl_map.auh_first_min_len += 8*(ch->sl_map.IV_length+ch->sl_map.KI_length);		}		ch->sl_map.auh_first_min_len += ch->sl_map.CTSDeltaLength;		ch->sl_map.auh_first_min_len += ch->sl_map.DTSDeltaLength;		ch->sl_map.auh_first_min_len += ch->sl_map.SizeLength;		ch->sl_map.auh_first_min_len += ch->sl_map.RandomAccessIndication;		ch->sl_map.auh_first_min_len += ch->sl_map.StreamStateIndication;		ch->sl_map.auh_min_len = ch->sl_map.auh_first_min_len;		ch->sl_map.auh_first_min_len += ch->sl_map.IndexLength;		ch->sl_map.auh_min_len += ch->sl_map.IndexDeltaLength;		/*RFC3016 flags*/		if (!stricmp(map->payload_name, "MP4V-ES")) {			ch->sl_map.StreamType = GF_STREAM_VISUAL;			ch->sl_map.ObjectTypeIndication = 0x20;		}		else if (!stricmp(map->payload_name, "MP4A-LATM")) {			ch->sl_map.StreamType = GF_STREAM_AUDIO;			ch->sl_map.ObjectTypeIndication = 0x40;		}		/*MPEG-4 video, check RAPs if not indicated*/		if ((ch->sl_map.StreamType == GF_STREAM_VISUAL) && (ch->sl_map.ObjectTypeIndication == 0x20) && !ch->sl_map.RandomAccessIndication) {			ch->flags |= RTP_M4V_CHECK_RAP;		}		break;	case GP_RTP_PAYT_MPEG12:		if (!stricmp(map->payload_name, "MPA")) {			ch->sl_map.StreamType = GF_STREAM_AUDIO;			ch->sl_map.ObjectTypeIndication = 0x69;		}		else if (!stricmp(map->payload_name, "MPV")) {			/*we signal RAPs*/			ch->sl_map.RandomAccessIndication = 1;			ch->sl_map.StreamType = GF_STREAM_VISUAL;			/*FIXME: how to differentiate MPEG1 from MPEG2 video before any frame is received??*/			ch->sl_map.ObjectTypeIndication = 0x6A;		}		break;	case GP_RTP_PAYT_AMR:	case GP_RTP_PAYT_AMR_WB:		{			GF_BitStream *bs;			ch->sl_map.StreamType = GF_STREAM_AUDIO;			ch->sl_map.ObjectTypeIndication = GPAC_EXTRA_CODECS_OTI;			/*create DSI*/			bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);			if (ch->rtptype == GP_RTP_PAYT_AMR) {				gf_bs_write_u32(bs, GF_4CC('s', 'a', 'm', 'r'));				gf_bs_write_u16(bs, 8000);				gf_bs_write_u16(bs, 160);			} else {				gf_bs_write_u32(bs, GF_4CC('s', 'a', 'w', 'b'));				gf_bs_write_u16(bs, 16000);				gf_bs_write_u16(bs, 320);			}			gf_bs_write_u8(bs, 1);			gf_bs_write_u8(bs, 16);			gf_bs_write_u8(bs, 1);			gf_bs_get_content(bs, &ch->sl_map.config, &ch->sl_map.configSize);			gf_bs_del(bs);		}		break;	case GP_RTP_PAYT_H263:		{			u32 x, y, w, h;			GF_X_Attribute *att;			GF_BitStream *bs;			x = y = w = h = 0;			j=0;			while ((att = (GF_X_Attribute *)gf_list_enum(media->Attributes, &j))) {				if (stricmp(att->Name, "cliprect")) continue;				/*only get the display area*/				sscanf(att->Value, "%d,%d,%d,%d", &y, &x, &h, &w);			}			ch->sl_map.StreamType = GF_STREAM_VISUAL;			ch->sl_map.ObjectTypeIndication = GPAC_EXTRA_CODECS_OTI;			/*create DSI*/			bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);			gf_bs_write_u32(bs, GF_4CC('h', '2', '6', '3'));			gf_bs_write_u16(bs, w);			gf_bs_write_u16(bs, h);			gf_bs_get_content(bs, &ch->sl_map.config, &ch->sl_map.configSize);			gf_bs_del(bs);			/*we signal RAPs*/			ch->sl_map.RandomAccessIndication = 1;		}		break;	case GP_RTP_PAYT_3GPP_TEXT:	{		char *tx3g, *a_tx3g;		GF_BitStream *bs;		u32 nb_desc;		GF_SDP_FMTP *fmtp;		GF_TextConfig tcfg;		memset(&tcfg, 0, sizeof(GF_TextConfig));		tcfg.tag = GF_ODF_TEXT_CFG_TAG;		tcfg.Base3GPPFormat = 0x10;		tcfg.MPEGExtendedFormat = 0x10;		tcfg.profileLevel = 0x10;		tcfg.timescale = ch->clock_rate;		tcfg.sampleDescriptionFlags = 1;		tx3g = NULL;		i=0;		while ((fmtp = (GF_SDP_FMTP*)gf_list_enum(media->FMTP, &i))) {			GF_X_Attribute *att;			if (fmtp->PayloadType != map->PayloadType) continue;			j=0;			while ((att = (GF_X_Attribute *)gf_list_enum(fmtp->Attributes, &j))) {				if (!stricmp(att->Name, "width")) tcfg.text_width = atoi(att->Value);				else if (!stricmp(att->Name, "height")) tcfg.text_height = atoi(att->Value);				else if (!stricmp(att->Name, "tx")) tcfg.horiz_offset = atoi(att->Value);				else if (!stricmp(att->Name, "ty")) tcfg.vert_offset = atoi(att->Value);				else if (!stricmp(att->Name, "layer")) tcfg.layer = atoi(att->Value);				else if (!stricmp(att->Name, "max-w")) tcfg.video_width = atoi(att->Value);				else if (!stricmp(att->Name, "max-h")) tcfg.video_height = atoi(att->Value);				else if (!stricmp(att->Name, "tx3g")) tx3g = att->Value;			}		}		if (!tx3g) return 0;		bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);		gf_bs_write_u8(bs, tcfg.Base3GPPFormat);		gf_bs_write_u8(bs, tcfg.MPEGExtendedFormat); /*MPEGExtendedFormat*/		gf_bs_write_u8(bs, tcfg.profileLevel); /*profileLevel*/		gf_bs_write_u24(bs, tcfg.timescale);		gf_bs_write_int(bs, 0, 1);	/*no alt formats*/		gf_bs_write_int(bs, tcfg.sampleDescriptionFlags, 2);		gf_bs_write_int(bs, 1, 1);	/*we will write sample desc*/		gf_bs_write_int(bs, 1, 1);	/*video info*/		gf_bs_write_int(bs, 0, 3);	/*reserved, spec doesn't say the values*/		gf_bs_write_u8(bs, tcfg.layer);		gf_bs_write_u16(bs, tcfg.text_width);		gf_bs_write_u16(bs, tcfg.text_height);		/*get all tx3g (comma separated)*/		nb_desc = 1;		a_tx3g = tx3g;		while ((a_tx3g = strchr(a_tx3g, ',')) ) {			a_tx3g ++;			nb_desc ++;		}		a_tx3g = tx3g;

⌨️ 快捷键说明

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