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

📄 rtp_pck_3gpp.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>static void rtp_amr_flush(GP_RTPPacketizer *builder){	char *hdr;	u32 hdr_size;	if (!builder->bytesInPacket) return;	gf_bs_get_content(builder->pck_hdr, &hdr, &hdr_size);	gf_bs_del(builder->pck_hdr);	builder->pck_hdr = NULL;	/*overwrite last frame F bit*/	hdr[builder->last_au_sn] &= 0x7F;	builder->OnData(builder->cbk_obj, hdr, hdr_size, 1);	free(hdr);	builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);	builder->bytesInPacket = 0;	builder->last_au_sn = 0;}GF_Err gp_rtp_builder_do_amr(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize){	u32 offset, rtp_ts, block_size;	if (!data) {		rtp_amr_flush(builder);		return GF_OK;	}	rtp_ts = (u32) builder->sl_header.compositionTimeStamp;	offset = 0;	while (data_size>offset) {		u8 ft = (data[offset] & 0x78) >> 3;		u8 size;		if (builder->rtp_payt == GF_RTP_PAYT_AMR_WB) {			size = GF_AMR_WB_FRAME_SIZE[ft];			block_size = 320;		} else {			size = GF_AMR_FRAME_SIZE[ft];			block_size = 160;		}		/*packet full or too long*/		if (builder->bytesInPacket + 1 + size > builder->Path_MTU)			rtp_amr_flush(builder);		/*need new*/		if (!builder->bytesInPacket) {			builder->rtp_header.TimeStamp = rtp_ts;			builder->rtp_header.Marker = 0;	/*never set*/			builder->rtp_header.SequenceNumber += 1;			builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);			assert(builder->pck_hdr==NULL);			/*always have header and TOC*/			builder->pck_hdr = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);			/*CMR + res (all 0, no interleaving)*/			gf_bs_write_int(builder->pck_hdr, ft, 4);			gf_bs_write_int(builder->pck_hdr, 0, 4);			builder->bytesInPacket = 1;			/*no interleaving*/		}		/*F always to 1*/		gf_bs_write_int(builder->pck_hdr, 1, 1);		gf_bs_write_int(builder->pck_hdr, ft, 4);		/*Q*/		gf_bs_write_int(builder->pck_hdr, (data[offset] & 0x4) ? 1 : 0, 1);		gf_bs_write_int(builder->pck_hdr, 0, 2);		builder->bytesInPacket ++;		/*remove frame type byte*/		offset++;		/*add frame data without rate_type byte header*/		if (builder->OnDataReference) {			builder->OnDataReference(builder->cbk_obj, size, offset);		} else {			builder->OnData(builder->cbk_obj, data+offset, size, 0);		}		builder->last_au_sn++;		builder->bytesInPacket += size;		offset += size;		rtp_ts += block_size;		assert(builder->bytesInPacket<=builder->Path_MTU);		/*take care of aggregation, flush if needed*/		if (builder->last_au_sn==builder->auh_size) rtp_amr_flush(builder);	}	return GF_OK;}static GFINLINE u8 qes_get_rate_size(u32 idx, u32 *rates, u32 nb_rates){	u32 i;	for (i=0; i<nb_rates; i++) {		if (rates[2*i]==idx) return rates[2*i+1];	}	return 0;}GF_Err gp_rtp_builder_do_qcelp(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize){	u32 offset, rtp_ts;	u8 hdr;	if (!data) {		if (builder->bytesInPacket) builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);		builder->bytesInPacket = 0;		builder->last_au_sn = 0;		return GF_OK;	}	rtp_ts = (u32) builder->sl_header.compositionTimeStamp;	offset = 0;	while (data_size>offset) {		u8 frame_type = data[offset];		u8 size = qes_get_rate_size(frame_type, (u32 *)GF_QCELP_RATE_TO_SIZE, GF_QCELP_RATE_TO_SIZE_NB);		/*reserved, not sent)*/		if (frame_type>=5) {			offset += size;			continue;		}		/*packet full or too long*/		if (builder->bytesInPacket + size > builder->Path_MTU) {			builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);			builder->bytesInPacket = 0;			builder->last_au_sn = 0;		}		/*need new*/		if (!builder->bytesInPacket) {			builder->rtp_header.TimeStamp = rtp_ts;			builder->rtp_header.Marker = 0;	/*never set*/			builder->rtp_header.SequenceNumber += 1;			builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);			hdr = 0;/*no interleaving*/			builder->OnData(builder->cbk_obj, (char*)&hdr, 1, 0);			builder->bytesInPacket = 1;		}		if (builder->OnDataReference) {			builder->OnDataReference(builder->cbk_obj, size, offset);		} else {			builder->OnData(builder->cbk_obj, data+offset, size, 0);		}		builder->bytesInPacket += size;		offset += size;		rtp_ts += 160;		assert(builder->bytesInPacket<=builder->Path_MTU);		/*take care of aggregation, flush if needed*/		builder->last_au_sn++;		if (builder->last_au_sn==builder->auh_size) {			builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);			builder->bytesInPacket = 0;			builder->last_au_sn = 0;		}	}	return GF_OK;}static void rtp_evrc_smv_flush(GP_RTPPacketizer *builder){	if (!builder->bytesInPacket) return;	if (builder->auh_size>1) {		char *hdr;		u32 hdr_size;		/*padding*/		if (builder->last_au_sn % 2) gf_bs_write_int(builder->pck_hdr, 0, 4);		gf_bs_get_content(builder->pck_hdr, &hdr, &hdr_size);		gf_bs_del(builder->pck_hdr);		builder->pck_hdr = NULL;		/*overwrite count*/		hdr[0] = 0;		hdr[1] = builder->last_au_sn-1;/*MMM + frameCount-1*/		builder->OnData(builder->cbk_obj, hdr, hdr_size, 1);		free(hdr);	}	builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);	builder->bytesInPacket = 0;	builder->last_au_sn = 0;}GF_Err gp_rtp_builder_do_smv(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize){	u32 offset, rtp_ts;	if (!data) {		rtp_evrc_smv_flush(builder);		return GF_OK;	}	rtp_ts = (u32) builder->sl_header.compositionTimeStamp;	offset = 0;	while (data_size>offset) {		u8 frame_type = data[offset];		u8 size = qes_get_rate_size(frame_type, (u32 *)GF_SMV_EVRC_RATE_TO_SIZE, GF_SMV_EVRC_RATE_TO_SIZE_NB);		/*reserved, not sent)*/		if (frame_type>=5) {			offset += size;			continue;		}		/*packet full or too long*/		if (builder->bytesInPacket + size > builder->Path_MTU) 			rtp_evrc_smv_flush(builder);		/*need new*/		if (!builder->bytesInPacket) {			builder->rtp_header.TimeStamp = rtp_ts;			builder->rtp_header.Marker = 0;	/*never set*/			builder->rtp_header.SequenceNumber += 1;			builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);			assert(builder->pck_hdr==NULL);			if (builder->auh_size>1) {				builder->pck_hdr = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);				/*RRLLLNNN (all 0, no interleaving)*/				gf_bs_write_u8(builder->pck_hdr, 0);				/*MMM + count-1 : overriden when flushing*/				gf_bs_write_u8(builder->pck_hdr, 0);				builder->bytesInPacket = 2;			}		}		/*bundle mode: cat rate byte to TOC, on 4 bits*/		if (builder->auh_size>1) {			gf_bs_write_int(builder->pck_hdr, data[offset], 4);			if (!(builder->last_au_sn % 2)) builder->bytesInPacket += 1;		}		/*note that EVEN in header-free format the rate_type byte is removed*/		offset++;		size--;		/*add frame data without rate_type byte header*/		if (builder->OnDataReference) {			builder->OnDataReference(builder->cbk_obj, size, offset);		} else {			builder->OnData(builder->cbk_obj, data+offset, size, 0);		}		builder->last_au_sn++;

⌨️ 快捷键说明

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