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

📄 cache.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 / MP4 cache 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 "isom_in.h"#ifndef GPAC_READ_ONLYstatic GF_Err ISOW_Open(GF_StreamingCache *mc, GF_ClientService *serv, const char *location_and_name, Bool keep_existing_files){	char szRoot[GF_MAX_PATH], szPath[GF_MAX_PATH], *ext;	ISOMReader *cache = (ISOMReader *)mc->priv;	if (cache->mov || cache->service) return GF_BAD_PARAM;	strcpy(szRoot, location_and_name);	ext = strrchr(szRoot, '.');	if (ext) ext[0] = 0;	strcpy(szPath, szRoot);	strcat(szPath, ".mp4");	if (keep_existing_files) {		FILE *f = fopen(szPath, "rb");		if (f) {			u32 i=0;			fclose(f);			while (1) {				sprintf(szPath, "%s_%04d.mp4", szRoot, i);				f = fopen(szPath, "rb");				if (!f) break;				fclose(f);				i++;			}		}	}		/*create a new movie in write mode (eg no editing)*/	cache->mov = gf_isom_open(szPath, GF_ISOM_OPEN_WRITE, NULL);	if (!cache->mov) return gf_isom_last_error(NULL);	cache->service = serv;	return GF_OK;}static GF_Err ISOW_Close(GF_StreamingCache *mc, Bool delete_cache){	GF_Err e;	ISOMReader *cache = (ISOMReader *)mc->priv;	if (!cache->mov || !cache->service) return GF_BAD_PARAM;	while (gf_list_count(cache->channels)) {		ISOMChannel *ch = (ISOMChannel *)gf_list_get(cache->channels, 0);		gf_list_rem(cache->channels, 0);		if (ch->cache_sample) {			gf_isom_add_sample(cache->mov, ch->track, 1, ch->cache_sample);			gf_isom_sample_del(&ch->cache_sample);		}		free(ch);	}	if (delete_cache) {		gf_isom_delete(cache->mov);		e = GF_OK;	} else {		e = gf_isom_close(cache->mov);	}	cache->mov = NULL;	cache->service = NULL;	return e;}static GF_Err ISOW_Write(GF_StreamingCache *mc, LPNETCHANNEL ch, char *data, u32 data_size, GF_SLHeader *sl_hdr){	ISOMChannel *mch;	GF_ESD *esd;	u32 di, mtype;	u64 DTS, CTS;	ISOMReader *cache = (ISOMReader *)mc->priv;	if (!cache->mov || !cache->service) return GF_BAD_PARAM;	mch = isor_get_channel(cache, ch);	if (!mch) {		Bool mapped;		GF_NetworkCommand com;		com.base.on_channel = ch;		com.base.command_type = GF_NET_CHAN_GET_ESD;		gf_term_on_command(cache->service, &com, GF_OK);		if (!com.cache_esd.esd) return GF_SERVICE_ERROR;		esd = (GF_ESD *)com.cache_esd.esd;		switch (esd->decoderConfig->streamType) {		case GF_STREAM_OD: mtype = GF_ISOM_MEDIA_OD; break;		case GF_STREAM_SCENE: mtype = GF_ISOM_MEDIA_SCENE; break;		case GF_STREAM_VISUAL: mtype = GF_ISOM_MEDIA_VISUAL; break;		case GF_STREAM_AUDIO: mtype = GF_ISOM_MEDIA_AUDIO; break;		case GF_STREAM_MPEG7: mtype = GF_ISOM_MEDIA_MPEG7; break;		case GF_STREAM_OCI: mtype = GF_ISOM_MEDIA_OCI; break;		case GF_STREAM_IPMP: mtype = GF_ISOM_MEDIA_IPMP; break;		case GF_STREAM_MPEGJ: mtype = GF_ISOM_MEDIA_MPEGJ; break;		case GF_STREAM_TEXT: mtype = GF_ISOM_MEDIA_TEXT; break;		default: return GF_NOT_SUPPORTED;		}		GF_SAFEALLOC(mch, ISOMChannel);		mch->time_scale = esd->slConfig->timestampResolution;		mch->streamType = esd->decoderConfig->streamType;		mch->track = gf_isom_new_track(cache->mov, com.cache_esd.esd->ESID, mtype, mch->time_scale);		mch->is_playing = 1;		mch->channel = ch;		mch->owner = cache;		gf_isom_set_track_enabled(cache->mov, mch->track, 1);		/*translate 3GP streams to MP4*/		mapped = 0;		if (esd->decoderConfig->objectTypeIndication==GPAC_EXTRA_CODECS_OTI) {			char szCode[5];			strncpy(szCode, esd->decoderConfig->decoderSpecificInfo->data, 4);			szCode[4]=0;			if (!stricmp(szCode, "samr") || !stricmp(szCode, "amr ") || !stricmp(szCode, "sawb")) {				GF_BitStream *bs;				GF_3GPConfig amrc;				mapped = 1;				memset(&amrc, 0, sizeof(GF_3GPConfig));				bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ);				gf_bs_skip_bytes(bs, 10);				amrc.frames_per_sample = (u32) gf_bs_read_u8(bs);				gf_bs_del(bs);				amrc.type = (!stricmp(szCode, "sawb")) ? GF_ISOM_SUBTYPE_3GP_AMR_WB : GF_ISOM_SUBTYPE_3GP_AMR;				amrc.vendor = GF_4CC('G','P','A','C');				gf_isom_3gp_config_new(cache->mov, mch->track, &amrc, NULL, NULL, &di);			} else if (!stricmp(szCode, "h263")) {				GF_3GPConfig h263c;				memset(&h263c, 0, sizeof(GF_3GPConfig));				h263c.type = GF_ISOM_SUBTYPE_3GP_H263;				h263c.vendor = GF_4CC('G','P','A','C');				gf_isom_3gp_config_new(cache->mov, mch->track, &h263c, NULL, NULL, &di);				mapped = 1;			}		} 		if (!mapped) gf_isom_new_mpeg4_description(cache->mov, mch->track, esd, NULL, NULL, &di);		if (com.cache_esd.is_iod_stream) gf_isom_add_track_to_root_od(cache->mov, mch->track);		gf_list_add(cache->channels, mch);	}	/*first sample, cache it*/	if (!mch->cache_sample) {		mch->cache_seed_ts = sl_hdr->decodingTimeStamp;		mch->cache_sample = gf_isom_sample_new();		mch->cache_sample->IsRAP = sl_hdr->randomAccessPointFlag;		mch->cache_sample->dataLength = data_size;		mch->cache_sample->data = (char*)malloc(sizeof(char)*data_size);		memcpy(mch->cache_sample->data, data, sizeof(char)*data_size);		return GF_OK;	}	/*adjust DTS/CTS*/	DTS = sl_hdr->decodingTimeStamp - mch->cache_seed_ts;	if ((mch->streamType==GF_STREAM_VISUAL) && (DTS<=mch->cache_sample->DTS)) {		assert(DTS>mch->prev_dts);		CTS = mch->cache_sample->DTS + mch->cache_sample->CTS_Offset;		mch->cache_sample->CTS_Offset = 0;		/*first time, shift all CTS*/		if (!mch->frame_cts_offset) {			u32 i, count = gf_isom_get_sample_count(cache->mov, mch->track);			mch->frame_cts_offset = (u32) (DTS-mch->prev_dts);			for (i=0; i<count; i++) {				gf_isom_modify_cts_offset(cache->mov, mch->track, i+1, mch->frame_cts_offset);			}			mch->cache_sample->CTS_Offset += mch->frame_cts_offset;		}		mch->cache_sample->DTS = mch->prev_dts + mch->frame_cts_offset;		mch->cache_sample->CTS_Offset += (u32) (CTS-mch->cache_sample->DTS);	}	/*deal with reference picture insertion: if no CTS offset and biggest CTS until now, this is 	a reference insertion - we must check that in order to make sure we have strictly increasing DTSs*/	if (mch->max_cts && !mch->cache_sample->CTS_Offset && (mch->cache_sample->DTS+mch->cache_sample->CTS_Offset > mch->max_cts)) {		assert(mch->cache_sample->DTS > mch->prev_dts + mch->frame_cts_offset);		CTS = mch->cache_sample->DTS + mch->cache_sample->CTS_Offset;		mch->cache_sample->DTS = mch->prev_dts + mch->frame_cts_offset;		mch->cache_sample->CTS_Offset = (u32) (CTS-mch->cache_sample->DTS);	}	if (mch->cache_sample->CTS_Offset) 		mch->max_cts = mch->cache_sample->DTS+mch->cache_sample->CTS_Offset;	/*add cache*/	gf_isom_add_sample(cache->mov, mch->track, 1, mch->cache_sample);	assert(!mch->prev_dts || (mch->prev_dts < mch->cache_sample->DTS));	mch->prev_dts = mch->cache_sample->DTS;	mch->duration = MAX(mch->max_cts, mch->prev_dts);	gf_isom_sample_del(&mch->cache_sample);	/*store sample*/	mch->cache_sample = gf_isom_sample_new();	mch->cache_sample->IsRAP = sl_hdr->randomAccessPointFlag;	mch->cache_sample->DTS = DTS + mch->frame_cts_offset;	mch->cache_sample->CTS_Offset = (u32) (sl_hdr->compositionTimeStamp - mch->cache_seed_ts - DTS);	mch->cache_sample->dataLength = data_size;	mch->cache_sample->data = (char*)malloc(sizeof(char)*data_size);	memcpy(mch->cache_sample->data, data, sizeof(char)*data_size);	return GF_OK;}static GF_Err ISOW_ServiceCommand(GF_StreamingCache *mc, GF_NetworkCommand *com){	ISOMReader *cache = (ISOMReader *)mc->priv;	if (!cache->mov || !cache->service) return GF_BAD_PARAM;	return GF_OK;}static GF_Err ISOW_ChannelGetSLP(GF_StreamingCache *mc, LPNETCHANNEL channel, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr, Bool *sl_compressed, GF_Err *out_reception_status, Bool *is_new_data){	ISOMReader *cache = (ISOMReader *)mc->priv;	if (!cache->mov || !cache->service) return GF_BAD_PARAM;	return GF_OK;}static GF_Err ISOW_ChannelReleaseSLP(GF_StreamingCache *mc, LPNETCHANNEL channel){	ISOMReader *cache = (ISOMReader *)mc->priv;	if (!cache->mov || !cache->service) return GF_BAD_PARAM;	return GF_OK;}GF_BaseInterface *isow_load_cache(){	ISOMReader *cache;	GF_StreamingCache *plug;	GF_SAFEALLOC(plug, GF_StreamingCache);	GF_REGISTER_MODULE_INTERFACE(plug, GF_STREAMING_MEDIA_CACHE, "GPAC IsoMedia Cache", "gpac distribution")	plug->Open = ISOW_Open;	plug->Close = ISOW_Close;	plug->Write = ISOW_Write;	plug->ChannelGetSLP = ISOW_ChannelGetSLP;	plug->ChannelReleaseSLP = ISOW_ChannelReleaseSLP;	plug->ServiceCommand = ISOW_ServiceCommand;	GF_SAFEALLOC(cache, ISOMReader);	cache->channels = gf_list_new();	plug->priv = cache;	return (GF_BaseInterface *) plug;}void isow_delete_cache(GF_BaseInterface *bi){	GF_StreamingCache *mc = (GF_StreamingCache*) bi;	ISOMReader *cache = (ISOMReader *)mc->priv;	gf_list_del(cache->channels);	free(cache);	free(bi);}#endif

⌨️ 快捷键说明

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