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

📄 rtp_pck_mpeg12.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			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 mpa12_do_flush(GP_RTPPacketizer *builder, Bool start_new){	char *tmp;	u32 tmp_size;	/*flush*/	if (builder->pck_hdr) {		gf_bs_get_content(builder->pck_hdr, &tmp, &tmp_size);		builder->OnData(builder->cbk_obj, tmp, tmp_size, 1);		free(tmp);		if (gf_bs_get_size(builder->payload)) {			gf_bs_get_content(builder->payload, &tmp, &tmp_size);			builder->OnData(builder->cbk_obj, tmp, tmp_size, 0);			free(tmp);		}		builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);		gf_bs_del(builder->pck_hdr);		gf_bs_del(builder->payload);		builder->pck_hdr = NULL;		builder->payload = NULL;		builder->bytesInPacket = 0;	}	if (!start_new) return;	builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp;	builder->pck_hdr = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);	builder->payload = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);	/*create new RTP Packet */	builder->rtp_header.SequenceNumber += 1;	builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);	builder->first_sl_in_rtp = 1;	builder->bytesInPacket = 0;}GF_Err gp_rtp_builder_do_mpeg12_audio(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize){	u32 pck_size;	u16 offset;	/*if no data flush, if nothing start if not enough space restart*/	if (!data || !builder->bytesInPacket || (builder->bytesInPacket + data_size > builder->Path_MTU)) {		mpa12_do_flush(builder, data ? 1 : 0);		if (!data) return GF_OK;	}	offset = 0;	while (data_size) {		if (data_size + 4 < builder->Path_MTU) {			pck_size = data_size;		} else {			pck_size = builder->Path_MTU - 4;		}		if (builder->first_sl_in_rtp) {			gf_bs_write_u16(builder->pck_hdr, 0);			gf_bs_write_u16(builder->pck_hdr, offset);			builder->first_sl_in_rtp = 0;			builder->bytesInPacket = 2;		}		/*add reference*/		if (builder->OnDataReference) 			builder->OnDataReference(builder->cbk_obj, pck_size, offset);		else			gf_bs_write_data(builder->payload, data + offset, pck_size);		data_size -= pck_size;		builder->bytesInPacket += pck_size;		/*start new packet if fragmenting*/		if (data_size) {			offset += (u16) pck_size;			mpa12_do_flush(builder, 1);		}	}	/*if offset or no aggregation*/	if (offset || !(builder->flags & GP_RTP_PCK_USE_MULTI) ) mpa12_do_flush(builder, 0);	return GF_OK;}s32 MPEG12_FindNextSliceStart(unsigned char *pbuffer, u32 startoffset, u32 buflen, u32 *slice_offset);s32 MPEG12_FindNextStartCode(unsigned char *pbuffer, u32 buflen, u32 *optr, u32 *scode);#define MPEG12_PICTURE_START_CODE         0x00000100#define MPEG12_SEQUENCE_START_CODE        0x000001b3GF_Err gp_rtp_builder_do_mpeg12_video(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize){	u32 startcode, pic_type, max_pck_size, offset, prev_slice, next_slice;	Bool start_with_slice, slices_done, got_slice, first_slice, have_seq;	char mpv_hdr[4];	char *payload, *buffer;	/*no flsuh (no aggregation)*/	if (!data) return GF_OK;	offset = 0;	have_seq = 0;    while (1) {		u32 oldoffset;		oldoffset = offset;		if (MPEG12_FindNextStartCode((unsigned char *) data + offset, data_size - offset, &offset, &startcode) < 0)			break;		offset += oldoffset;		if (startcode == MPEG12_SEQUENCE_START_CODE) have_seq = 1;		offset += 4;		if (startcode == MPEG12_PICTURE_START_CODE) break;	}	max_pck_size = builder->Path_MTU - 4;	payload = data + offset;	pic_type = (payload[1] >> 3) & 0x7;	/*first 6 bits (MBZ and T bit) not used*/	/*temp ref on 10 bits*/    mpv_hdr[0] = (payload[0] >> 6) & 0x3;    mpv_hdr[1] = (payload[0] << 2) | ((payload[1] >> 6) & 0x3);    mpv_hdr[2] = pic_type;    mpv_hdr[3] = 0;    if ((pic_type==2) || (pic_type== 3)) {		mpv_hdr[3] = payload[3] << 5;		if ((payload[4] & 0x80) != 0) mpv_hdr[3] |= 0x10;		if (pic_type == 3) mpv_hdr[3] |= (payload[4] >> 3) & 0xf;	}	/*start packet*/	builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp;	builder->rtp_header.Marker = 1;	builder->rtp_header.SequenceNumber += 1;	builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);	buffer = data;    prev_slice = 0;	start_with_slice = (MPEG12_FindNextSliceStart((unsigned char *)buffer, offset, data_size, &next_slice) >= 0) ? 1 : 0;    offset = 0;	slices_done = 0;	got_slice = start_with_slice;	first_slice = 1;	while (data_size > 0) {		Bool last_pck;		u32 len_to_write;				if (data_size <= max_pck_size) {			len_to_write = data_size;			last_pck = 1; 			prev_slice = 0;		} else {			got_slice = (!first_slice && !slices_done && (next_slice <= max_pck_size)) ? 1 : 0;			first_slice = 0;			last_pck = 0;						while (!slices_done && (next_slice <= max_pck_size)) {				prev_slice = next_slice;				if (MPEG12_FindNextSliceStart((unsigned char *)buffer, next_slice + 4, data_size, &next_slice) >= 0) {					got_slice = 1;				} else {					slices_done = 1;				}			}			if (got_slice) len_to_write = prev_slice;			else len_to_write = MIN(max_pck_size, data_size);		} 		mpv_hdr[2] = pic_type;				if (have_seq) {			mpv_hdr[2] |= 0x20;			have_seq = 0;		}		if (first_slice) mpv_hdr[2] |= 0x10;				if (got_slice || last_pck) {			mpv_hdr[2] |= 0x08;			start_with_slice = 1;		} else {			start_with_slice = 0;		}				builder->OnData(builder->cbk_obj, mpv_hdr, 4, 0);		if (builder->OnDataReference) {			builder->OnDataReference(builder->cbk_obj, len_to_write, offset);		} else {			builder->OnData(builder->cbk_obj, data + offset, len_to_write, 0);		}				builder->rtp_header.Marker = last_pck ? 1 : 0;		builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header);				offset += len_to_write;		data_size -= len_to_write;		prev_slice = 0;		next_slice -= len_to_write;		buffer += len_to_write;		if (!last_pck) {			builder->rtp_header.Marker = 0;			builder->rtp_header.SequenceNumber += 1;			builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header);		}    }	return GF_OK;}

⌨️ 快捷键说明

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