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

📄 rtp_depacketizer.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 <gpac/internal/ietf_dev.h>#include <gpac/esi.h>#include <gpac/base_coding.h>#include <gpac/constants.h>#include <gpac/mpeg4_odf.h>#include <gpac/avparse.h>static void gf_rtp_parse_mpeg4(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size){	u32 aux_size, au_size, first_idx, au_hdr_size, pay_start, num_au;	s32 au_idx;	GF_BitStream *hdr_bs, *aux_bs;	hdr_bs = gf_bs_new(payload, size, GF_BITSTREAM_READ);	aux_bs = gf_bs_new(payload, size, GF_BITSTREAM_READ);//	printf("parsing packet %d size %d ts %d M %d\n", hdr->SequenceNumber, size, hdr->TimeStamp, hdr->Marker);	/*global AU header len*/	au_hdr_size = 0;	if (rtp->sl_map.auh_first_min_len) {		au_hdr_size = gf_bs_read_u16(hdr_bs);		gf_bs_read_u16(aux_bs);	}	/*jump to aux section, skip it and get payload start*/	gf_bs_read_int(aux_bs, au_hdr_size);	gf_bs_align(aux_bs);	if (rtp->sl_map.AuxiliaryDataSizeLength) {		aux_size = gf_bs_read_int(aux_bs, rtp->sl_map.AuxiliaryDataSizeLength);		gf_bs_read_int(aux_bs, aux_size);		gf_bs_align(aux_bs);	}	pay_start = (u32) gf_bs_get_position(aux_bs);	gf_bs_del(aux_bs);	first_idx = 0;	au_idx = 0;	rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;	rtp->sl_hdr.decodingTimeStamp = hdr->TimeStamp;	num_au = 0;	rtp->sl_hdr.accessUnitEndFlag = hdr->Marker;	/*override some defaults for RFC 3016*/	if (rtp->flags & GF_RTP_NEW_AU) {		rtp->sl_hdr.accessUnitStartFlag = 1;	} else {		rtp->sl_hdr.accessUnitStartFlag = 0;	}	rtp->sl_hdr.randomAccessPointFlag = 0;	while (1) {		/*get default AU size*/		au_size = rtp->sl_map.ConstantSize;		/*not signaled, assume max one AU per packet*/		if (!au_size) au_size = size - pay_start;				if ((!num_au && rtp->sl_map.auh_first_min_len) || (num_au && rtp->sl_map.auh_min_len)) {			/*ISMACryp*/			if (rtp->flags & GF_RTP_HAS_ISMACRYP) {				rtp->sl_hdr.isma_encrypted = 1;				if (rtp->flags & GF_RTP_ISMA_SEL_ENC) {					rtp->sl_hdr.isma_encrypted = gf_bs_read_int(hdr_bs, 1);					gf_bs_read_int(hdr_bs, 7);				}				/*Note: ISMACryp ALWAYS indicates IV (BSO) and KEYIDX, even when sample is not encrypted. 				This is quite a waste when using selective encryption....*/				if (!num_au) {					rtp->sl_hdr.isma_BSO = gf_bs_read_int(hdr_bs, 8*rtp->sl_map.IV_length);				}				/*NOT SUPPORTED YET*/				else if (rtp->sl_map.IV_delta_length) {					rtp->sl_hdr.isma_BSO += gf_bs_read_int(hdr_bs, 8*rtp->sl_map.IV_delta_length);				}				if (rtp->sl_map.KI_length) {					/*NOT SUPPORTED YET*/					if (!num_au || !(rtp->flags & GF_RTP_ISMA_HAS_KEY_IDX) ) {						gf_bs_skip_bytes(hdr_bs, rtp->sl_map.KI_length);					}				}			}			/*AU size*/			if (rtp->sl_map.SizeLength) {				au_size = gf_bs_read_int(hdr_bs, rtp->sl_map.SizeLength);				if (au_size > size - pay_start) au_size = size - pay_start;				au_hdr_size -= rtp->sl_map.SizeLength;			}			/*AU index*/			if (! num_au) {				au_idx = first_idx = gf_bs_read_int(hdr_bs, rtp->sl_map.IndexLength);				au_hdr_size -= rtp->sl_map.IndexLength;			} else {				au_idx += 1 + (s32) gf_bs_read_int(hdr_bs, rtp->sl_map.IndexDeltaLength);				au_hdr_size -= rtp->sl_map.IndexDeltaLength;			}			/*CTS flag*/			if (rtp->sl_map.CTSDeltaLength) {				rtp->sl_hdr.compositionTimeStampFlag = gf_bs_read_int(hdr_bs, 1);				au_hdr_size -= 1;			} else {				/*get CTS from IDX*/				if (rtp->sl_map.ConstantDuration) {					rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp + (au_idx - first_idx) * rtp->sl_map.ConstantDuration;				} else {					rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp + (au_idx - first_idx) * rtp->sl_hdr.au_duration;				}			}			/*CTS in-band*/			if (rtp->sl_hdr.compositionTimeStampFlag) {				rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp + (s32) gf_bs_read_int(hdr_bs, rtp->sl_map.CTSDeltaLength);				au_hdr_size -= rtp->sl_map.CTSDeltaLength;			}			/*DTS flag is always present (needed for reconstruction of TSs in case of packet loss)*/			if (rtp->sl_map.DTSDeltaLength) {				rtp->sl_hdr.decodingTimeStampFlag = gf_bs_read_int(hdr_bs, 1);				au_hdr_size -= 1;			} else {				/*NO DTS otherwise*/				rtp->sl_hdr.decodingTimeStampFlag = 0;			}			if (rtp->sl_hdr.decodingTimeStampFlag) {				u32 ts_off = gf_bs_read_int(hdr_bs, rtp->sl_map.DTSDeltaLength);				/*TODO FIXME may not be true in case of TS wrapping*/				if (hdr->TimeStamp > ts_off) rtp->sl_hdr.decodingTimeStamp = hdr->TimeStamp - ts_off;				au_hdr_size -= rtp->sl_map.DTSDeltaLength;			}			/*RAP flag*/			if (rtp->sl_map.RandomAccessIndication) {				rtp->sl_hdr.randomAccessPointFlag = gf_bs_read_int(hdr_bs, 1);				au_hdr_size -= 1;			}			/*stream state - map directly to seqNum*/			if (rtp->sl_map.StreamStateIndication) {				rtp->sl_hdr.AU_sequenceNumber = gf_bs_read_int(hdr_bs, rtp->sl_map.StreamStateIndication);				au_hdr_size -= rtp->sl_map.StreamStateIndication;			} else {				rtp->sl_hdr.AU_sequenceNumber = au_idx;			}		}		/*no header present, update CTS/DTS - note we're sure there's no interleaving*/		else {			if (num_au) {				rtp->sl_hdr.compositionTimeStamp += rtp->sl_map.ConstantDuration;				rtp->sl_hdr.decodingTimeStamp += rtp->sl_map.ConstantDuration;			}		}		/*we cannot map RTP SN to SL SN since an RTP packet may carry several SL ones - only inc by 1 seq nums*/		rtp->sl_hdr.packetSequenceNumber += 1;		/*force indication of CTS whenever we have a new AU*/				rtp->sl_hdr.compositionTimeStampFlag = (rtp->flags & GF_RTP_NEW_AU) ? 1 : 0;		/*locate VOP start code*/		if (rtp->sl_hdr.accessUnitStartFlag && (rtp->flags & GF_RTP_M4V_CHECK_RAP)) {			u32 i;			Bool is_rap = 0;			unsigned char *pay = (unsigned char *) payload + pay_start;			i=0;			while (i<au_size-4) {				if (!pay[i] && !pay[i+1] && (pay[i+2]==1) && (pay[i+3]==0xB6)) {					is_rap = ((pay[i+4] & 0xC0)==0) ? 1 : 0;					break;				}				i++;			}			rtp->sl_hdr.randomAccessPointFlag = is_rap ? 1 : 0;		}		rtp->on_sl_packet(rtp->udta, payload + pay_start, au_size, &rtp->sl_hdr, GF_OK);		rtp->sl_hdr.compositionTimeStampFlag = 0;				if (rtp->flags & GF_RTP_HAS_ISMACRYP) rtp->sl_hdr.isma_BSO += au_size;		if (au_hdr_size < rtp->sl_map.auh_min_len) break;		pay_start += au_size;		if (pay_start >= size) break;		num_au ++;	}	if (hdr->Marker)		rtp->flags |= GF_RTP_NEW_AU;	else		rtp->flags &= ~GF_RTP_NEW_AU;	gf_bs_del(hdr_bs);}static void gf_rtp_parse_mpeg12_audio(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size){	u16 offset;	u32 mp3hdr, ts;	GF_BitStream *bs;	rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;	rtp->sl_hdr.decodingTimeStamp = hdr->TimeStamp;	rtp->sl_hdr.accessUnitStartFlag = rtp->sl_hdr.accessUnitEndFlag ? 1 : 0;	if (rtp->flags & GF_RTP_NEW_AU) rtp->sl_hdr.accessUnitStartFlag = 1;	/*get frag header*/	bs = gf_bs_new(payload, size, GF_BITSTREAM_READ);	gf_bs_read_u16(bs);	offset = gf_bs_read_u16(bs);	gf_bs_del(bs);	payload += 4;	size -= 4;	mp3hdr = 0;	while (1) {		/*frame start if no offset*/		rtp->sl_hdr.accessUnitStartFlag = offset ? 0 : 1;		/*new frame, store size*/		rtp->sl_hdr.compositionTimeStampFlag = 0;		if (rtp->sl_hdr.accessUnitStartFlag) {			mp3hdr = GF_4CC((u8) payload[0], (u8) payload[1], (u8) payload[2], (u8) payload[3]);			rtp->sl_hdr.accessUnitLength = gf_mp3_frame_size(mp3hdr);			rtp->sl_hdr.compositionTimeStampFlag = 1;		}		if (!rtp->sl_hdr.accessUnitLength) break;		/*fragmented frame*/		if (rtp->sl_hdr.accessUnitLength>size) {			rtp->on_sl_packet(rtp->udta, payload, rtp->sl_hdr.accessUnitLength, &rtp->sl_hdr, GF_OK);			rtp->sl_hdr.accessUnitLength -= size;			rtp->sl_hdr.accessUnitStartFlag = rtp->sl_hdr.accessUnitEndFlag = 0;			return;		}		/*complete frame*/		rtp->sl_hdr.accessUnitEndFlag = 1;		rtp->on_sl_packet(rtp->udta, payload, rtp->sl_hdr.accessUnitLength, &rtp->sl_hdr, GF_OK);		payload += rtp->sl_hdr.accessUnitLength;		size -= rtp->sl_hdr.accessUnitLength;		rtp->sl_hdr.accessUnitLength = 0;				/*if fragmented there shall not be other frames in the packet*/		if (!rtp->sl_hdr.accessUnitStartFlag) return;		if (!size) break;		offset = 0;		/*get ts*/		ts = gf_mp3_window_size(mp3hdr);		rtp->sl_hdr.compositionTimeStamp += ts;		rtp->sl_hdr.decodingTimeStamp += ts;	}	rtp->flags |= GF_RTP_NEW_AU;}static void gf_rtp_parse_mpeg12_video(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size){	u8 pic_type;	rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;	rtp->sl_hdr.decodingTimeStamp = hdr->TimeStamp;	pic_type = payload[2] & 0x7;	payload += 4;	size -= 4;	/*missed something*/	if (rtp->sl_hdr.compositionTimeStamp != hdr->TimeStamp) rtp->flags |= GF_RTP_NEW_AU;	rtp->sl_hdr.accessUnitStartFlag = (rtp->flags & GF_RTP_NEW_AU) ? 1 : 0;	rtp->sl_hdr.accessUnitEndFlag = hdr->Marker ? 1 : 0;	rtp->sl_hdr.randomAccessPointFlag = (pic_type==1) ? 1 : 0;	if (rtp->sl_hdr.accessUnitStartFlag) {		rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;		rtp->sl_hdr.compositionTimeStampFlag = 1;	} else {		rtp->sl_hdr.compositionTimeStampFlag = 0;	}	rtp->on_sl_packet(rtp->udta, payload, size, &rtp->sl_hdr, GF_OK);	if (hdr->Marker) {		rtp->flags |= GF_RTP_NEW_AU;	} else {		rtp->flags &= ~GF_RTP_NEW_AU;	}}static void gf_rtp_parse_amr(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size){	unsigned char c, type;	char *data;	/*we support max 30 frames in one RTP packet...*/	u32 nbFrame, i, frame_size;	/*not supported yet*/	if (!(rtp->flags & GF_RTP_AMR_ALIGN) ) return;	/*process toc and locate start of payload data*/	nbFrame = 0;	while (1) {		c = payload[nbFrame + 1];		nbFrame++;		if (!(c & 0x80)) break;	}	data = payload + nbFrame + 1;	rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;	/*then each frame*/	for (i=0; i<nbFrame; i++) {		c = payload[i + 1];		type = ((c & 0x78) >> 3);		if (rtp->payt==GF_RTP_PAYT_AMR) {			frame_size = GF_AMR_FRAME_SIZE[type];		} else {			frame_size = GF_AMR_WB_FRAME_SIZE[type];		}		rtp->sl_hdr.compositionTimeStampFlag = 1;		rtp->sl_hdr.accessUnitStartFlag = 1;		rtp->sl_hdr.accessUnitEndFlag = 0;		/*send TOC*/		rtp->on_sl_packet(rtp->udta, &payload[i+1], 1, &rtp->sl_hdr, GF_OK);		rtp->sl_hdr.packetSequenceNumber ++;		rtp->sl_hdr.compositionTimeStampFlag = 0;		rtp->sl_hdr.accessUnitStartFlag = 0;		rtp->sl_hdr.accessUnitEndFlag = 1;		/*send payload*/		rtp->on_sl_packet(rtp->udta, data, frame_size, &rtp->sl_hdr, GF_OK);		data += frame_size;		rtp->sl_hdr.compositionTimeStamp += 160;	}}static void gf_rtp_parse_h263(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size){	GF_BitStream *bs;	Bool P_bit, V_bit;	u32 plen, plen_bits, offset;	char blank[2];	bs = gf_bs_new(payload, size, GF_BITSTREAM_READ);	/*reserved*/	gf_bs_read_int(bs, 5);	P_bit = gf_bs_read_int(bs, 1);	V_bit = gf_bs_read_int(bs, 1);	plen = gf_bs_read_int(bs, 6);	plen_bits = gf_bs_read_int(bs, 3);	/*VRC not supported yet*/	if (V_bit) {		gf_bs_read_u8(bs);	}	/*extra picture header not supported yet*/	if (plen) {		gf_bs_skip_bytes(bs, plen);	}	offset = (u32) gf_bs_get_position(bs);	gf_bs_del(bs);	blank[0] = blank[1] = 0;	/*start*/	if (P_bit) {		rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;		rtp->sl_hdr.compositionTimeStampFlag = 1;		rtp->sl_hdr.accessUnitStartFlag = 1;		rtp->sl_hdr.accessUnitEndFlag = 0;		if (rtp->sl_hdr.accessUnitStartFlag) {			/*the first 16 bytes are NOT sent on the wire*/			rtp->sl_hdr.randomAccessPointFlag = (payload[offset+2]&0x02) ? 0 : 1;		}		/*send missing start code*/		rtp->on_sl_packet(rtp->udta, (char *) blank, 2, &rtp->sl_hdr, GF_OK);		/*send payload*/		rtp->sl_hdr.compositionTimeStampFlag = 0;		rtp->sl_hdr.accessUnitStartFlag = 0;		rtp->sl_hdr.randomAccessPointFlag = 0;		/*if M bit set, end of frame*/		rtp->sl_hdr.accessUnitEndFlag = hdr->Marker;		rtp->on_sl_packet(rtp->udta, payload + offset, size - offset, &rtp->sl_hdr, GF_OK);	} else {		/*middle/end of frames - if M bit set, end of frame*/		rtp->sl_hdr.accessUnitEndFlag = hdr->Marker;		rtp->on_sl_packet(rtp->udta, payload + offset, size - offset, &rtp->sl_hdr, GF_OK);	}}static void gf_rtp_ttxt_flush(GF_RTPDepacketizer *rtp, u32 ts){	GF_BitStream *bs;	char *data;	u32 data_size;	if (!rtp->inter_bs) return;	rtp->sl_hdr.compositionTimeStamp = ts;	rtp->sl_hdr.compositionTimeStampFlag = 1;	rtp->sl_hdr.accessUnitStartFlag = 1;	rtp->sl_hdr.accessUnitEndFlag = 0;	rtp->sl_hdr.randomAccessPointFlag = 1;	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);	gf_bs_write_int(bs, rtp->sl_hdr.idleFlag, 1);	rtp->sl_hdr.idleFlag = 0;

⌨️ 快捷键说明

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