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

📄 saf_in.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Authors: Jean le Feuvre *				Copyright (c) 2005-200X ENST *					All rights reserved * *  This file is part of GPAC / SAF reader 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/modules/service.h>#include <gpac/modules/codec.h>#include <gpac/constants.h>#include <gpac/thread.h>typedef struct{	LPNETCHANNEL ch;	u32 au_sn, stream_id, ts_res, buffer_min;	GF_ESD *esd;} SAFChannel;enum{	SAF_FILE_LOCAL,	SAF_FILE_REMOTE,	SAF_LIVE_STREAM};typedef struct{	GF_ClientService *service;	GF_List *channels;	Bool needs_connection;	u32 saf_type;	/*file downloader*/	GF_DownloadSession * dnload;	/*SAF buffer for both lcoal, remote and live streams*/	char *saf_data;	u32 saf_size, alloc_size;	/*local file playing*/	GF_Thread *th;	FILE *stream;	u32 run_state;	u32 start_range, end_range;	Double duration;	u32 nb_playing;} SAFIn;static GFINLINE SAFChannel *saf_get_channel(SAFIn *saf, u32 stream_id, LPNETCHANNEL a_ch){	SAFChannel *ch;	u32 i=0;	while ((ch = (SAFChannel *)gf_list_enum(saf->channels, &i))) {		if (ch->stream_id==stream_id) return ch;		if (a_ch && (ch->ch==a_ch)) return ch;	}	return NULL;}static Bool SAF_CanHandleURL(GF_InputService *plug, const char *url){	char *sExt;	sExt = strrchr(url, '.');	if (!sExt) return 0;	if (gf_term_check_extension(plug, "application/x-saf", "saf lsr", "SAF Rich Media", sExt)) return 1;	return 0;}static void SAF_Regulate(SAFIn *read){	GF_NetworkCommand com;	SAFChannel *ch;	com.command_type = GF_NET_CHAN_BUFFER_QUERY;	/*sleep untill the buffer occupancy is too low - note that this work because all streams in this	demuxer are synchronized*/	while (read->run_state) {		u32 min_occ = (u32) -1;		u32 i=0;		while ( (ch = (SAFChannel *)gf_list_enum(read->channels, &i))) {			com.base.on_channel = ch->ch;			gf_term_on_command(read->service, &com, GF_OK);			if (com.buffer.occupancy < ch->buffer_min) return;			if (com.buffer.occupancy) min_occ = MIN(min_occ, com.buffer.occupancy - ch->buffer_min);		}		if (min_occ == (u32) -1) break;		//fprintf(stdout, "Regulating SAF demux - sleeping for %d ms\n", min_occ);		gf_sleep(min_occ);	}}static void SAF_NetIO(void *cbk, GF_NETIO_Parameter *param){	GF_Err e;	Bool is_rap, go;	SAFChannel *ch;	u32 cts, au_sn, au_size, bs_pos, type, i, stream_id;	GF_BitStream *bs;	GF_SLHeader sl_hdr;		SAFIn *read = (SAFIn *) cbk;	e = param->error;	/*done*/	if (param->msg_type==GF_NETIO_DATA_TRANSFERED) {		if (read->stream && (read->saf_type==SAF_FILE_REMOTE)) read->saf_type = SAF_FILE_LOCAL;		return;	} else {		/*handle service message*/		gf_term_download_update_stats(read->dnload);		if (param->msg_type!=GF_NETIO_DATA_EXCHANGE) {			if (e<0) {				if (read->needs_connection) {					read->needs_connection = 0;					gf_term_on_connect(read->service, NULL, e);				}				return;			}			if (read->needs_connection) {				u32 total_size;				gf_dm_sess_get_stats(read->dnload, NULL, NULL, &total_size, NULL, NULL, NULL);				if (!total_size) read->saf_type = SAF_LIVE_STREAM;			}			return;		}	}	if (!param->size) return;	if (!read->run_state) return;	if (read->alloc_size < read->saf_size + param->size) {		read->saf_data = (char*)realloc(read->saf_data, sizeof(char)*(read->saf_size + param->size) );		read->alloc_size = read->saf_size + param->size;	}	memcpy(read->saf_data + read->saf_size, param->data, sizeof(char)*param->size);	read->saf_size += param->size;	/*first AU not complete yet*/	if (read->saf_size<10) return;	bs = gf_bs_new(read->saf_data, read->saf_size, GF_BITSTREAM_READ);	bs_pos = 0;	go = 1;	while (go) {		u32 avail = (u32) gf_bs_available(bs);		bs_pos = (u32) gf_bs_get_position(bs);		if (avail<10) break;		is_rap = gf_bs_read_int(bs, 1);		au_sn = gf_bs_read_int(bs, 15);		gf_bs_read_int(bs, 2);		cts = gf_bs_read_int(bs, 30);		au_size = gf_bs_read_int(bs, 16);		avail-=8;		if (au_size > avail) break;		assert(au_size>=2);		is_rap = 1;		type = gf_bs_read_int(bs, 4);		stream_id = gf_bs_read_int(bs, 12);		au_size -= 2;		ch = saf_get_channel(read, stream_id, NULL);		switch (type) {		case 1:		case 2:		case 7:			if (ch) {				gf_bs_skip_bytes(bs, au_size);			} else {				SAFChannel *first = (SAFChannel *)gf_list_get(read->channels, 0);				GF_SAFEALLOC(ch, SAFChannel);				ch->stream_id = stream_id;				ch->esd = gf_odf_desc_esd_new(0);				ch->esd->ESID = stream_id;				ch->esd->OCRESID = first ? first->stream_id : stream_id;				ch->esd->slConfig->useRandomAccessPointFlag = 1;				ch->esd->slConfig->AUSeqNumLength = 0;				ch->esd->decoderConfig->objectTypeIndication = gf_bs_read_u8(bs);				ch->esd->decoderConfig->streamType = gf_bs_read_u8(bs);				ch->ts_res = ch->esd->slConfig->timestampResolution = gf_bs_read_u24(bs);				ch->esd->decoderConfig->bufferSizeDB = gf_bs_read_u16(bs);				au_size -= 7;				if ((ch->esd->decoderConfig->objectTypeIndication == 0xFF) && (ch->esd->decoderConfig->streamType == 0xFF) ) {					u16 mimeLen = gf_bs_read_u16(bs);					gf_bs_skip_bytes(bs, mimeLen);					au_size -= mimeLen+2;				}				if (type==7) {					u16 urlLen = gf_bs_read_u16(bs);					ch->esd->URLString = (char*)malloc(sizeof(char)*(urlLen+1));					gf_bs_read_data(bs, ch->esd->URLString, urlLen);					ch->esd->URLString[urlLen] = 0;					au_size -= urlLen+2;				}				if (au_size) {					ch->esd->decoderConfig->decoderSpecificInfo->dataLength = au_size;					ch->esd->decoderConfig->decoderSpecificInfo->data = (char*)malloc(sizeof(char)*au_size);					gf_bs_read_data(bs, ch->esd->decoderConfig->decoderSpecificInfo->data, au_size);				}				if (ch->esd->decoderConfig->streamType==4) ch->buffer_min=100;				else if (ch->esd->decoderConfig->streamType==5) ch->buffer_min=400;				else ch->buffer_min=0;				if (read->needs_connection && (ch->esd->decoderConfig->streamType==GF_STREAM_SCENE)) {					gf_list_add(read->channels, ch);					read->needs_connection = 0;					gf_term_on_connect(read->service, NULL, GF_OK);				} else if (read->needs_connection) {					gf_odf_desc_del((GF_Descriptor *) ch->esd);					free(ch);					ch = NULL;				} else {					GF_ObjectDescriptor *od;					gf_list_add(read->channels, ch);					od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG);					gf_list_add(od->ESDescriptors, ch->esd);					ch->esd = NULL;					od->objectDescriptorID = ch->stream_id;					gf_term_add_media(read->service, (GF_Descriptor*)od, 0);				}			}			break;		case 4:			if (ch) {				bs_pos = (u32) gf_bs_get_position(bs);				memset(&sl_hdr, 0, sizeof(GF_SLHeader));				sl_hdr.accessUnitLength = au_size;				sl_hdr.AU_sequenceNumber = au_sn;				sl_hdr.compositionTimeStampFlag = 1;				sl_hdr.compositionTimeStamp = cts;				sl_hdr.randomAccessPointFlag = is_rap;				if (read->start_range && (read->start_range*ch->ts_res>cts*1000)) {					sl_hdr.compositionTimeStamp = read->start_range*ch->ts_res/1000;				}				gf_term_on_sl_packet(read->service, ch->ch, read->saf_data+bs_pos, au_size, &sl_hdr, GF_OK);			}			gf_bs_skip_bytes(bs, au_size);			break;		case 3:			if (ch) gf_term_on_sl_packet(read->service, ch->ch, NULL, 0, NULL, GF_EOS);			break;		case 5:			go = 0;			read->run_state = 0;			i=0;			while ((ch = (SAFChannel *)gf_list_enum(read->channels, &i))) {				gf_term_on_sl_packet(read->service, ch->ch, NULL, 0, NULL, GF_EOS);			}			break;		}	}	gf_bs_del(bs);	if (bs_pos) {		u32 remain = read->saf_size - bs_pos;		if (remain) memmove(read->saf_data, read->saf_data+bs_pos, sizeof(char)*remain);		read->saf_size = remain;	}	SAF_Regulate(read);}u32 SAF_Run(void *_p){	GF_NETIO_Parameter par;	char data[1024];	SAFIn *read = (SAFIn *)_p;	par.msg_type = GF_NETIO_DATA_EXCHANGE;	par.data = data;

⌨️ 快捷键说明

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