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

📄 saf.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Authors: Jean le Feuvre *				Copyright (c) 2005-200X ENST *					All rights reserved * *  This file is part of GPAC / LASeR codec 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/media_dev.h>#include <gpac/bitstream.h>#include <gpac/thread.h>enum{	SAF_STREAM_HEADER = 1,	SAF_STREAM_HEADER_PERMANENT = 2,	SAF_END_OF_STREAM = 3,	SAF_ACCESS_UNIT = 4,	SAF_END_OF_SESSION = 5,	SAF_CACHE_UNIT = 6,	SAF_REMOTE_STREAM_HEADER = 7,};typedef struct{	char *data;	u32 data_size;	Bool is_rap;	u32 ts;} GF_SAFSample;typedef struct{	u32 stream_id;	u32 ts_resolution;	u32 buffersize_db;	u8 stream_type, object_type;	char *mime_type;	char *remote_url;	char *dsi;	u32 dsi_len;	GF_List *aus;	/*0: not declared yet; 1: declared; (1<<1) : done but end of stream not sent yet*/	u32 state;	u32 last_au_sn, last_au_ts;} GF_SAFStream;struct __saf_muxer{	GF_List *streams;	/*0: nothing to do, 1: should regenerate, (1<<1): end of session has been sent*/	u32 state;	GF_Mutex *mx;};GF_SAFMuxer *gf_saf_mux_new(){	GF_SAFMuxer *mux;	GF_SAFEALLOC(mux, GF_SAFMuxer);	mux->mx = gf_mx_new();	mux->streams = gf_list_new();	return mux;}static void saf_stream_del(GF_SAFStream *str){	if (str->mime_type) free(str->mime_type);	if (str->remote_url) free(str->remote_url);	if (str->dsi) free(str->dsi);	while (gf_list_count(str->aus)) {		GF_SAFSample *au = (GF_SAFSample *)gf_list_last(str->aus);		gf_list_rem_last(str->aus);		if (au->data) free(au->data);		free(au);	}	gf_list_del(str->aus);	free(str);}void gf_saf_mux_del(GF_SAFMuxer *mux){	while (gf_list_count(mux->streams)) {		GF_SAFStream *str = (GF_SAFStream *)gf_list_last(mux->streams);		gf_list_rem_last(mux->streams);		saf_stream_del(str);	}	gf_list_del(mux->streams);	gf_mx_del(mux->mx);	free(mux);}static GFINLINE GF_SAFStream *saf_get_stream(GF_SAFMuxer *mux, u32 stream_id){	GF_SAFStream *str;	u32 i=0;	while ( (str = (GF_SAFStream *)gf_list_enum(mux->streams, &i)) ) {		if (str->stream_id==stream_id) return str;	}	return NULL;}GF_Err gf_saf_mux_stream_add(GF_SAFMuxer *mux, u32 stream_id, u32 ts_res, u32 buffersize_db, u8 stream_type, u8 object_type, char *mime_type, char *dsi, u32 dsi_len, char *remote_url){	GF_SAFStream *str = saf_get_stream(mux, stream_id);	if (str) return GF_BAD_PARAM;	if (mux->state == 2) return GF_BAD_PARAM;	gf_mx_p(mux->mx);	GF_SAFEALLOC(str, GF_SAFStream);	str->stream_id = stream_id;	str->ts_resolution = ts_res;	str->buffersize_db = buffersize_db;	str->stream_type = stream_type;	str->object_type = object_type;	if (mime_type) {		str->mime_type = strdup(mime_type);		str->stream_type = str->object_type = 0xFF;	}	str->dsi_len = dsi_len;	if (dsi_len) {		str->dsi = (char *) malloc(sizeof(char)*dsi_len);		memcpy(str->dsi, dsi, sizeof(char)*dsi_len);	}	if (remote_url) str->remote_url = strdup(remote_url);	str->aus = gf_list_new();	mux->state = 0;	gf_list_add(mux->streams, str);	gf_mx_v(mux->mx);	return GF_OK;}GF_Err gf_saf_mux_stream_rem(GF_SAFMuxer *mux, u32 stream_id){	GF_SAFStream *str = saf_get_stream(mux, stream_id);	if (!str) return GF_BAD_PARAM;	if (mux->state == 2) return GF_BAD_PARAM;	gf_mx_p(mux->mx);	str->state |= 2;	mux->state = 1;	gf_mx_v(mux->mx);	return GF_OK;}GF_Err gf_saf_mux_add_au(GF_SAFMuxer *mux, u32 stream_id, u32 CTS, char *data, u32 data_len, Bool is_rap){	GF_SAFSample *au;	GF_SAFStream *str = saf_get_stream(mux, stream_id);	if (!str) return GF_BAD_PARAM;	if (mux->state == 2) return GF_BAD_PARAM;	gf_mx_p(mux->mx);	GF_SAFEALLOC(au, GF_SAFSample);	au->data = data;	au->data_size = data_len;	au->is_rap = is_rap;	au->ts = CTS;	mux->state = 1;	gf_list_add(str->aus, au);	gf_mx_v(mux->mx);	return GF_OK;}GF_Err gf_saf_mux_for_time(GF_SAFMuxer *mux, u32 time_ms, Bool force_end_of_session, char **out_data, u32 *out_size){	u32 i, count, dlen;	char *data;	GF_SAFStream *str;	GF_SAFSample*au;	GF_BitStream *bs, *payload;	*out_data = NULL;	*out_size = 0;		gf_mx_p(mux->mx);	if (!force_end_of_session && (mux->state!=1)) {		gf_mx_v(mux->mx);		return GF_OK;	}	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);	count = gf_list_count(mux->streams);	/*1: write all stream headers*/	for (i=0; i<count; i++) {		str = (GF_SAFStream *)gf_list_get(mux->streams, i);		if (str->state & 1) continue;		au = (GF_SAFSample *)gf_list_get(str->aus, 0);		/*write stream declaration*/		payload = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);		gf_bs_write_int(payload, str->remote_url ? SAF_REMOTE_STREAM_HEADER : SAF_STREAM_HEADER, 4);		gf_bs_write_int(payload, str->stream_id, 12);		gf_bs_write_u8(payload, str->object_type);		gf_bs_write_u8(payload, str->stream_type);		gf_bs_write_int(payload, str->ts_resolution, 24);		gf_bs_write_u16(payload, str->buffersize_db);		if (str->mime_type) {			u32 len = strlen(str->mime_type);			gf_bs_write_u16(payload, len);			gf_bs_write_data(payload, str->mime_type, len);		}		if (str->remote_url) {			u32 len = strlen(str->remote_url);			gf_bs_write_u16(payload, len);			gf_bs_write_data(payload, str->remote_url, len);		} 		if (str->dsi) {			gf_bs_write_data(payload, str->dsi, str->dsi_len);		}		gf_bs_get_content(payload, &data, &dlen);		gf_bs_del(payload);		/*write SAF packet header*/		gf_bs_write_int(bs, 1, 1);		gf_bs_write_int(bs, 0, 15);		gf_bs_write_int(bs, 0, 1);		gf_bs_write_int(bs, 1, 1);		gf_bs_write_int(bs, au ? au->ts : 0, 30);		gf_bs_write_int(bs, dlen, 16);		gf_bs_write_data(bs, data, dlen);		free(data);				/*mark as signaled*/		str->state |= 1;	}	/*write all pending AUs*/	while (1) {		GF_SAFStream *src = NULL;		u32 mux_time = time_ms;		for (i=0; i<count; i++) {			str = (GF_SAFStream*)gf_list_get(mux->streams, i);			au = (GF_SAFSample*)gf_list_get(str->aus, 0);			if (au && (au->ts*1000 < mux_time*str->ts_resolution)) {				mux_time = 1000*au->ts/str->ts_resolution;				src = str;			}		}		if (!src) break;		au = (GF_SAFSample*)gf_list_get(src->aus, 0);		gf_list_rem(src->aus, 0);		/*write stream declaration*/		gf_bs_write_int(bs, au->is_rap ? 1 : 0, 1);		gf_bs_write_int(bs, src->last_au_sn, 15);		gf_bs_write_int(bs, 0, 1);		gf_bs_write_int(bs, 1, 1);		gf_bs_write_int(bs, au->ts, 30);		gf_bs_write_u16(bs, 2+au->data_size);		gf_bs_write_int(bs, SAF_ACCESS_UNIT, 4);		gf_bs_write_int(bs, src->stream_id, 12);		gf_bs_write_data(bs, au->data, au->data_size);		src->last_au_sn ++;		src->last_au_ts = au->ts;		free(au->data);		free(au);	}	/*3: write all end of stream*/	for (i=0; i<count; i++) {		str = (GF_SAFStream*)gf_list_get(mux->streams, i);		/*mark as signaled*/		if (!(str->state & 2)) continue;		if (gf_list_count(str->aus)) continue;		/*write stream declaration*/		gf_bs_write_int(bs, 1, 1);		gf_bs_write_int(bs, str->last_au_sn, 15);		gf_bs_write_int(bs, 0, 1);		gf_bs_write_int(bs, 1, 1);		gf_bs_write_int(bs, str->last_au_ts, 30);		gf_bs_write_int(bs, 2, 16);		gf_bs_write_int(bs, SAF_END_OF_STREAM, 4);		gf_bs_write_int(bs, str->stream_id, 12);		/*remove stream*/		gf_list_rem(mux->streams, i);		i--;		count--;		saf_stream_del(str);	}	mux->state = 0;	if (force_end_of_session) {		gf_bs_write_int(bs, 1, 1);		gf_bs_write_int(bs, 0, 15);		gf_bs_write_int(bs, 0, 1);		gf_bs_write_int(bs, 1, 1);		gf_bs_write_int(bs, 0, 30);		gf_bs_write_int(bs, 2, 16);		gf_bs_write_int(bs, SAF_END_OF_SESSION, 4);		gf_bs_write_int(bs, 0, 12);		mux->state = 2;	}	gf_bs_get_content(bs, out_data, out_size);	gf_bs_del(bs);	gf_mx_v(mux->mx);	return GF_OK;}

⌨️ 快捷键说明

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