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

📄 main.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Cyril Concolato / Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / mp4 simple streamer application * *  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/isomedia.h>#include <gpac/ietf.h>#include <gpac/config.h>#include <gpac/base_coding.h>GP_RTPPacketizer *gf_rtp_packetizer_create_and_init_from_file(GF_ISOFile *file, 															  u32 TrackNum,															  void *cbk_obj, 															  void (*OnNewPacket)(void *cbk, GF_RTPHeader *header),															  void (*OnPacketDone)(void *cbk, GF_RTPHeader *header),															  void (*OnDataReference)(void *cbk, u32 payload_size, u32 offset_from_orig),															  void (*OnData)(void *cbk, char *data, u32 data_size, Bool is_head),															  u32 Path_MTU, 															  u32 max_ptime, 															  u32 default_rtp_rate, 															  u32 flags, 															  u8 PayloadID, 															  Bool copy_media, 															  u32 InterleaveGroupID, 															  u8 InterleaveGroupPriority);void gf_hinter_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdpLine, GF_ISOFile *file, u32 track);//------------------------------------------------------------// Define//------------------------------------------------------------#define PATHFILE "."#define RTP_HEADER_SIZE 12 // in bytes (octets)#define BASE_PAYT		96//------------------------------------------------------------// Typedef//------------------------------------------------------------enum{	LOG_NONE = 0,	LOG_BURST,	LOG_AU,	LOG_PACKET,};typedef struct {		u32 log_level;	u32 path_mtu;	struct __tag_rtp_session *session;	u8 payt;		Bool burst_mode;	/*burst mode configuration*/	u32 burstDuration;	u32 burstBitRate;	u32 burstSize;	u32 offDuration;	u32 averageBitRate;	u32 cycleDuration;	u32 nbBurstSent;} Streamer;typedef struct __tag_rtp_pck {	struct __tag_rtp_pck *next;	GF_RTPHeader header;	char *payload;	u32 payload_len;} RTP_Packet;typedef struct __tag_rtp_stream{	struct __tag_rtp_stream *next;	u32 current_au;	u32 nb_aus;	u32 port;	GF_RTPChannel *channel; 	GP_RTPPacketizer *packetizer;	GF_ISOSample  *au; // the AU	u32 track;	u32 sample_duration;	u32 sample_desc_index;	/*normalized DTS in micro-sec*/	u64 microsec_dts;	/* The previous packet which could not be sent in previous burst*/	RTP_Packet *pck_queue;	/* The current packet being formed */	RTP_Packet packet;	u32 ts_offset, microsec_ts_offset;	u32 next_ts;	Double ts_scale, microsec_ts_scale;	Bool process_burst;	struct __tag_rtp_session *session;} RTP_Stream;typedef struct __tag_rtp_session{	struct __tag_rtp_session *next;	u32 id;	u32 minBurstSize; // max size to fill the burst with the media bitRate	u32 looping; // 1: play the media in a loop, 0 play once	char *filename;	GF_ISOFile *mp4File;	u32 nbBurstSent; // pour cette session	u32 timelineOrigin; // time when the first burts was sent. this time <=> (CTS=0)	u32 nextBurstTime;	u32 dataLengthInBurst; // total bytes filled in current burst	s32 drift;	Bool force_mpeg4_generic;	/*list of streams in session*/	RTP_Stream *stream;	/*to sync looping sessions with tracks of # length*/	u32 duration;	Streamer *streamer;} RTP_Session;static void rtp_flush_channel(RTP_Stream *rtp){	u32 currentPacketSize; 	RTP_Packet *pck = rtp->pck_queue;	while (pck) {		RTP_Packet *tmp = pck;		gf_rtp_send_packet(rtp->channel, &pck->header, 0, 0, pck->payload, pck->payload_len);		currentPacketSize = (pck->payload_len + RTP_HEADER_SIZE);		rtp->session->dataLengthInBurst+= currentPacketSize; 		if (rtp->session->streamer->log_level == LOG_PACKET) fprintf(stdout, "  RTP SN %u - TS %u - M %u - Size %u\n", pck->header.SequenceNumber, pck->header.TimeStamp, pck->header.Marker, currentPacketSize);		pck = pck->next;		free(tmp->payload);		free(tmp);	}	rtp->pck_queue = NULL;}/* * callback functions, called by the RTP packetiser  *//* * The RTP packetizer is starting a new RTP packet and is giving the header */static void burst_on_pck_new(void *cbk, GF_RTPHeader *header){	RTP_Stream *rtp = cbk;	if (!header) return;	memcpy(&rtp->packet.header, header, sizeof(GF_RTPHeader));} /* OnNewPacket *//* * The RTP packetiser is done with the current RTP packet * the header may have changed since the beginning of the packet (OnNewPacket) *  */static void burst_on_pck_done(void *cbk, GF_RTPHeader *header) {	GF_Err e;	s64 burst_time, rtp_ts;	RTP_Stream *rtp = cbk;	u32 currentPacketSize; // in bits	currentPacketSize = (rtp->packet.payload_len + RTP_HEADER_SIZE);	burst_time = (s64) rtp->packetizer->sl_config.timestampResolution * (rtp->session->nextBurstTime + rtp->session->streamer->cycleDuration);	rtp_ts = (s64) rtp->next_ts*1000;	if (rtp->session->dataLengthInBurst + currentPacketSize < rtp->session->streamer->burstSize 		&& (burst_time - rtp_ts > 0) ) { 				e = gf_rtp_send_packet(rtp->channel, header, 0, 0, rtp->packet.payload, rtp->packet.payload_len);		if (e) 			fprintf(stdout, "Error %s sending RTP packet\n", gf_error_to_string(e));		rtp->session->dataLengthInBurst += currentPacketSize; 		free(rtp->packet.payload);						rtp->packet.payload = NULL;		rtp->packet.payload_len = 0;				if (rtp->session->streamer->log_level == LOG_PACKET) fprintf(stdout, "  RTP SN %u - TS %u - M %u - Size %u\n", rtp->packet.header.SequenceNumber, rtp->packet.header.TimeStamp, rtp->packet.header.Marker, currentPacketSize);	} else {		RTP_Packet *pck;		if (rtp->session->dataLengthInBurst + currentPacketSize > rtp->session->streamer->burstSize) {			if (rtp->session->streamer->log_level >= LOG_BURST) 				fprintf(stdout, "  Packet (TS %u) delayed due to buffer overflow\n", rtp->next_ts);		} else {			if (rtp->session->streamer->log_level==LOG_PACKET)				fprintf(stdout, "  Packet (TS %u) delayed to avoid drift\n", rtp->next_ts);		}		GF_SAFEALLOC(pck, RTP_Packet);		memcpy(&pck->header, header, sizeof(GF_RTPHeader));		pck->payload = rtp->packet.payload;		pck->payload_len = rtp->packet.payload_len;		rtp->packet.payload = NULL;		rtp->packet.payload_len = 0;				rtp->process_burst = 0;		if (rtp->pck_queue) {			RTP_Packet *first = rtp->pck_queue;			while (first->next) first = first->next;			first->next = pck;		} else {			rtp->pck_queue = pck;		}	}} /* OnPacketdone *//* * The RTP packetiser has added data to the current RTP packet */static void burst_on_pck_data(void *cbk, char *data, u32 data_size, Bool is_head) {	RTP_Stream *rtp = cbk;	if (!data ||!data_size) return;	if (!rtp->packet.payload_len) {		rtp->packet.payload = malloc(data_size);		memcpy(rtp->packet.payload, data, data_size);		rtp->packet.payload_len = data_size;	} else {		rtp->packet.payload = realloc(rtp->packet.payload, rtp->packet.payload_len + data_size);		if (!is_head) {			memcpy(rtp->packet.payload+rtp->packet.payload_len, data, data_size);		} else {			memmove(rtp->packet.payload+data_size, rtp->packet.payload, rtp->packet.payload_len);			memcpy(rtp->packet.payload, data, data_size);		}		rtp->packet.payload_len += data_size;	}	} /* OnData *//* * The RTP packetizer is starting a new RTP packet and is giving the header */static void on_pck_new(void *cbk, GF_RTPHeader *header){	RTP_Stream *rtp = cbk;	if (!header) return;	memcpy(&rtp->packet.header, header, sizeof(GF_RTPHeader));} /* * The RTP packetiser is done with the current RTP packet * the header may have changed since the beginning of the packet (OnNewPacket) *  */static void on_pck_done(void *cbk, GF_RTPHeader *header) {	RTP_Stream *rtp = cbk;	GF_Err e = gf_rtp_send_packet(rtp->channel, header, 0, 0, rtp->packet.payload, rtp->packet.payload_len);	if (e) 		fprintf(stdout, "Error %s sending RTP packet\n", gf_error_to_string(e));	free(rtp->packet.payload);					rtp->packet.payload = NULL;	rtp->packet.payload_len = 0;		if (rtp->session->streamer->log_level == LOG_PACKET) fprintf(stdout, "  RTP SN %u - TS %u - M %u - Size %u\n", rtp->packet.header.SequenceNumber, rtp->packet.header.TimeStamp, rtp->packet.header.Marker, rtp->packet.payload_len + RTP_HEADER_SIZE);}GF_Err rtp_init_packetizer(RTP_Stream *rtp, char *dest_ip){		u32 flags = 0;	if (rtp->session->force_mpeg4_generic) flags = GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_FORCE_MPEG4;	if (rtp->session->streamer->burst_mode) {		rtp->packetizer = gf_rtp_packetizer_create_and_init_from_file(rtp->session->mp4File, rtp->track, rtp,												burst_on_pck_new, burst_on_pck_done, NULL, burst_on_pck_data,												rtp->session->streamer->path_mtu, 0, 0, flags, 												rtp->session->streamer->payt, 0, 0, 0);	} else {		rtp->packetizer = gf_rtp_packetizer_create_and_init_from_file(rtp->session->mp4File, rtp->track, rtp,												on_pck_new, on_pck_done, NULL, burst_on_pck_data,												rtp->session->streamer->path_mtu, 0, 0, flags, 												rtp->session->streamer->payt, 0, 0, 0);	}	rtp->session->streamer->payt++;	rtp->ts_scale = rtp->packetizer->sl_config.timestampResolution;	rtp->ts_scale /= gf_isom_get_media_timescale(rtp->session->mp4File, rtp->track);	rtp->microsec_ts_scale = 1000000;	rtp->microsec_ts_scale /= gf_isom_get_media_timescale(rtp->session->mp4File, rtp->track);	return GF_OK;}GF_Err rtp_setup_sdp(RTP_Session *session, char *dest_ip){		RTP_Stream *rtp;	FILE *sdp_out;	char filename[30];	char mediaName[30], payloadName[30];	char sdpLine[20000];	sprintf(filename, "session%d.sdp", session->id);	sdp_out = fopen(filename, "wt");	if (!sdp_out) return GF_IO_ERR;	sprintf(sdpLine, "v=0");	fprintf(sdp_out, "%s\n", sdpLine);	sprintf(sdpLine, "o=MP4Streamer 3357474383 1148485440000 IN IP%d %s", gf_net_is_ipv6(dest_ip) ? 6 : 4, dest_ip);	fprintf(sdp_out, "%s\n", sdpLine);	sprintf(sdpLine, "s=livesession");	fprintf(sdp_out, "%s\n", sdpLine);	sprintf(sdpLine, "i=This is an MP4 time-sliced Streaming demo");	fprintf(sdp_out, "%s\n", sdpLine);	sprintf(sdpLine, "u=http://gpac.sourceforge.net");	fprintf(sdp_out, "%s\n", sdpLine);	sprintf(sdpLine, "e=admin@");	fprintf(sdp_out, "%s\n", sdpLine);	sprintf(sdpLine, "c=IN IP%d %s", gf_net_is_ipv6(dest_ip) ? 6 : 4, dest_ip);	fprintf(sdp_out, "%s\n", sdpLine);	sprintf(sdpLine, "t=0 0");	fprintf(sdp_out, "%s\n", sdpLine);	sprintf(sdpLine, "a=x-copyright: Streamed with GPAC (C)2000-200X - http://gpac.sourceforge.net\n");	fprintf(sdp_out, "%s\n", sdpLine);	rtp = session->stream;	while (rtp) {		gf_rtp_builder_get_payload_name(rtp->packetizer, payloadName, mediaName);				sprintf(sdpLine, "m=%s %d RTP/%s %d", mediaName, rtp->port, rtp->packetizer->slMap.IV_length ? "SAVP" : "AVP", rtp->packetizer->PayloadType);		fprintf(sdp_out, "%s\n", sdpLine);		sprintf(sdpLine, "a=rtpmap:%d %s/%d", rtp->packetizer->PayloadType, payloadName, rtp->packetizer->sl_config.timestampResolution);		fprintf(sdp_out, "%s\n", sdpLine);				if (gf_isom_get_media_type(rtp->session->mp4File, rtp->track) == GF_ISOM_MEDIA_VISUAL) {			u32 w, h;			w = h = 0;			gf_isom_get_visual_info(rtp->session->mp4File, rtp->track, 1, &w, &h);			if (rtp->packetizer->rtp_payt == GF_RTP_PAYT_H263) {				sprintf(sdpLine, "a=cliprect:0,0,%d,%d", h, w);			}

⌨️ 快捷键说明

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