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

📄 encode_isom.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / Scene Management 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/scene_manager.h>#include <gpac/constants.h>#include <gpac/media_tools.h>#include <gpac/bifs.h>#ifndef GPAC_DISABLE_SVG#include <gpac/laser.h>#include <gpac/nodes_svg_da.h>#endif#include <gpac/internal/scenegraph_dev.h>#ifndef GPAC_READ_ONLYstatic GF_MuxInfo *gf_sm_get_mux_info(GF_ESD *src){	u32 i;	GF_MuxInfo *mux;	i=0;	while ((mux = (GF_MuxInfo *)gf_list_enum(src->extensionDescriptors, &i))) {		if (mux->tag == GF_ODF_MUXINFO_TAG) return mux;	}	return NULL;}static void gf_sm_remove_mux_info(GF_ESD *src){	u32 i;	GF_MuxInfo *mux;	i=0;	while ((mux = (GF_MuxInfo *)gf_list_enum(src->extensionDescriptors, &i))) {		if (mux->tag == GF_ODF_MUXINFO_TAG) {			gf_odf_desc_del((GF_Descriptor *)mux);			gf_list_rem(src->extensionDescriptors, i-1);			return;		}	}}static void gf_sm_finalize_mux(GF_ISOFile *mp4, GF_ESD *src, u32 offset_ts){	u32 track, mts, ts;	GF_MuxInfo *mux = gf_sm_get_mux_info(src);	if (!mux && !offset_ts) return;	track = gf_isom_get_track_by_id(mp4, src->ESID);	if (!track) return;	mts = gf_isom_get_media_timescale(mp4, track);	ts = gf_isom_get_timescale(mp4);	/*set track time offset*/	if (mux) offset_ts += mux->startTime * mts / 1000;	if (offset_ts) {		u32 off = offset_ts * ts  / mts;		u64 dur = gf_isom_get_media_duration(mp4, track);		dur = dur * ts / mts;		gf_isom_set_edit_segment(mp4, track, 0, off, 0, GF_ISOM_EDIT_EMPTY);		gf_isom_set_edit_segment(mp4, track, off, dur, 0, GF_ISOM_EDIT_NORMAL);	}	/*set track interleaving ID*/	if (mux) {		if (mux->GroupID) gf_isom_set_track_group(mp4, track, mux->GroupID);		if (mux->import_flags & GF_IMPORT_USE_COMPACT_SIZE) 			gf_isom_use_compact_size(mp4, track, 1);	}}static GF_Err gf_sm_import_ui_stream(GF_ISOFile *mp4, GF_ESD *src){	GF_UIConfig *cfg;	u32 len, i;	GF_Err e;	if (!src->slConfig) src->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);	src->slConfig->predefined = 2;	src->slConfig->timestampResolution = 1000;	if (!src->decoderConfig || !src->decoderConfig->decoderSpecificInfo) return GF_ODF_INVALID_DESCRIPTOR;	if (src->decoderConfig->decoderSpecificInfo->tag == GF_ODF_UI_CFG_TAG) {		cfg = (GF_UIConfig *) src->decoderConfig->decoderSpecificInfo;		e = gf_odf_encode_ui_config(cfg, &src->decoderConfig->decoderSpecificInfo);		gf_odf_desc_del((GF_Descriptor *) cfg);		if (e) return e;	} else if (src->decoderConfig->decoderSpecificInfo->tag != GF_ODF_DSI_TAG) {		return GF_ODF_INVALID_DESCRIPTOR;	}	/*what's the media type for input sensor ??*/	len = gf_isom_new_track(mp4, src->ESID, GF_ISOM_MEDIA_SCENE, 1000);	if (!len) return gf_isom_last_error(mp4);	gf_isom_set_track_enabled(mp4, len, 1);	if (!src->ESID) src->ESID = gf_isom_get_track_id(mp4, len);	return gf_isom_new_mpeg4_description(mp4, len, src, NULL, NULL, &i);}static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD *src, char *mediaSource){	u32 track, di;	GF_Err e;	Bool isAudio, isVideo;	char szName[1024];	char *ext;	GF_MediaImporter import;	GF_MuxInfo *mux = NULL;	/*no import if URL string*/	if (src->URLString) {		u32 mtype, track;		if (!src->slConfig) src->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);		if (!src->decoderConfig) {			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] ESD with URL string needs a decoder config with remote stream type to be encoded\n"));			return GF_BAD_PARAM;		}		/*however we still need a track to store the ESD ...*/		switch (src->decoderConfig->streamType) {		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_IPMP:			mtype = GF_ISOM_MEDIA_IPMP;			break;		case GF_STREAM_OCI:			mtype = GF_ISOM_MEDIA_OCI;			break;		case GF_STREAM_MPEGJ:			mtype = GF_ISOM_MEDIA_MPEGJ;			break;		case GF_STREAM_INTERACT:		case GF_STREAM_SCENE:			mtype = GF_ISOM_MEDIA_SCENE;			break;		case GF_STREAM_TEXT:			mtype = GF_ISOM_MEDIA_TEXT;			break;		default:			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] Unsupported media type %d for ESD with URL string\n", src->decoderConfig->streamType));			return GF_BAD_PARAM;		}		track = gf_isom_new_track(mp4, src->ESID, mtype, 1000);		if (!src->ESID) src->ESID = gf_isom_get_track_id(mp4, track);		return gf_isom_new_mpeg4_description(mp4, track, src, NULL, NULL, &di);	}	/*look for muxInfo*/	mux = gf_sm_get_mux_info(src);	/*special streams*/	if (src->decoderConfig) {		/*InputSensor*/		if (src->decoderConfig->decoderSpecificInfo && (src->decoderConfig->decoderSpecificInfo->tag == GF_ODF_UI_CFG_TAG)) 			src->decoderConfig->streamType = GF_STREAM_INTERACT;		if (src->decoderConfig->streamType == GF_STREAM_INTERACT) return gf_sm_import_ui_stream(mp4, src);	}	/*OCR streams*/	if (src->decoderConfig && src->decoderConfig->streamType == GF_STREAM_OCR) {		track = gf_isom_new_track(mp4, src->ESID, GF_ISOM_MEDIA_OCR, 1000);		if (!track) return gf_isom_last_error(mp4);		gf_isom_set_track_enabled(mp4, track, 1);		if (!src->ESID) src->ESID = gf_isom_get_track_id(mp4, track);		if (!src->slConfig) src->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);		src->slConfig->predefined = 2;		e = gf_isom_new_mpeg4_description(mp4, track, src, NULL, NULL, &di);		if (e) return e;		if (mux && mux->duration) 			e = gf_isom_set_edit_segment(mp4, track, 0, mux->duration * gf_isom_get_timescale(mp4) / 1000, 0, GF_ISOM_EDIT_NORMAL);		return e;	}	if (!mux) {		/*if existing don't import (systems tracks)*/		track = gf_isom_get_track_by_id(mp4, src->ESID);		if (track) return GF_OK;		if (mediaSource) {			memset(&import, 0, sizeof(GF_MediaImporter));			import.dest = mp4;			import.trackID = src->ESID;			import.orig = gf_isom_open(mediaSource, GF_ISOM_OPEN_READ, NULL);			if (import.orig) {				e = gf_media_import(&import);				gf_isom_delete(import.orig);				return e;			}		}		return GF_OK;	}	if (!mux->file_name) return GF_OK;	memset(&import, 0, sizeof(GF_MediaImporter));	strcpy(szName, mux->file_name);	ext = strrchr(szName, '.');		/*get track types for AVI*/	if (ext && !strnicmp(ext, ".avi", 4)) {		isAudio = isVideo = 0;		if (ext && !stricmp(ext, ".avi#video")) isVideo = 1;		else if (ext && !stricmp(ext, ".avi#audio")) isAudio = 1;		else if (src->decoderConfig) {			if (src->decoderConfig->streamType == GF_STREAM_VISUAL) isVideo = 1;			else if (src->decoderConfig->streamType == GF_STREAM_AUDIO) isAudio = 1;		}		if (!isAudio && !isVideo) {			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] missing track specifier for AVI import (file#audio, file#video)\n"));			return GF_NOT_SUPPORTED;		}		if (isVideo) import.trackID = 1;		else import.trackID = 2;		ext = strchr(ext, '#');		if (ext) ext[0] = 0;	}	/*get track ID for MP4/others*/	if (ext) {		ext = strchr(ext, '#');		if (ext) {			import.trackID = atoi(ext+1);			ext[0] = 0;		}	}	import.streamFormat = mux->streamFormat;	import.dest = mp4;	import.esd = src;	import.duration = mux->duration;	import.flags = mux->import_flags;	import.video_fps = mux->frame_rate;	import.in_name = szName;	e = gf_media_import(&import);	if (e) return e;	/*if desired delete input*/	if (mux->delete_file) gf_delete_file(mux->file_name);	return e;}static GF_Err gf_sm_import_stream_special(GF_SceneManager *ctx, GF_ESD *esd){	GF_Err e;	GF_MuxInfo *mux = gf_sm_get_mux_info(esd);	if (!mux || !mux->file_name) return GF_OK;		if (esd->decoderConfig && esd->decoderConfig->decoderSpecificInfo		&& (esd->decoderConfig->decoderSpecificInfo->tag==GF_ODF_TEXT_CFG_TAG)) return GF_OK;	e = GF_OK;	/*SRT/SUB BIFS import if text node unspecified*/	if (mux->textNode) {		e = gf_sm_import_bifs_subtitle(ctx, esd, mux);		gf_sm_remove_mux_info(esd);	}	return e;}static GF_Err gf_sm_import_specials(GF_SceneManager *ctx){	GF_Err e;	u32 i, j, n, m, k;	GF_ESD *esd;	GF_AUContext *au;	GF_StreamContext *sc;	i=0;	while ((sc = (GF_StreamContext*)gf_list_enum(ctx->streams, &i))) {		if (sc->streamType != GF_STREAM_OD) continue;		esd = NULL;		j=0;		while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) {			GF_ODCom *com;			k=0;			while ((com = (GF_ODCom *) gf_list_enum(au->commands, &k))) {				switch (com->tag) {				case GF_ODF_OD_UPDATE_TAG:				{					GF_ObjectDescriptor *od;					GF_ODUpdate *odU = (GF_ODUpdate *)com;					n=0;					while ((od = (GF_ObjectDescriptor *) gf_list_enum(odU->objectDescriptors, &n))) {						GF_ESD *imp_esd;						m=0;						while ((imp_esd = (GF_ESD*)gf_list_enum(od->ESDescriptors, &m))) {							e = gf_sm_import_stream_special(ctx, imp_esd);							if (e != GF_OK) return e;						}					}				}					break;				case GF_ODF_ESD_UPDATE_TAG:				{					GF_ESD *imp_esd;					GF_ESDUpdate *esdU = (GF_ESDUpdate *)com;					m=0;					while ((imp_esd = (GF_ESD*)gf_list_enum(esdU->ESDescriptors, &m))) {						e = gf_sm_import_stream_special(ctx, imp_esd);						if (e != GF_OK) return e;					}				}					break;				}			}		}	}	return GF_OK;}/*locate stream in all OD updates/ESD updates (needed for systems tracks)*/static GF_ESD *gf_sm_locate_esd(GF_SceneManager *ctx, u16 ES_ID){	u32 i, j, n, m, k;	GF_ESD *esd;	GF_AUContext *au;	GF_StreamContext *sc;	if (!ES_ID) return NULL;	i=0;	while ((sc = (GF_StreamContext*)gf_list_enum(ctx->streams, &i))) {		if (sc->streamType != GF_STREAM_OD) continue;		esd = NULL;		j=0;		while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) {			GF_ODCom *com;			k=0;			while ((com = (GF_ODCom *) gf_list_enum(au->commands, &k))) {				switch (com->tag) {				case GF_ODF_OD_UPDATE_TAG:				{					GF_ObjectDescriptor *od;					GF_ODUpdate *odU = (GF_ODUpdate *)com;					n=0;					while ((od = (GF_ObjectDescriptor *) gf_list_enum(odU->objectDescriptors, &n))) {						GF_ESD *imp_esd;						m=0;						while ((imp_esd = (GF_ESD*)gf_list_enum(od->ESDescriptors, &m))) {							if (imp_esd->ESID == ES_ID) return imp_esd;						}					}				}					break;				case GF_ODF_ESD_UPDATE_TAG:				{					GF_ESD *imp_esd;					GF_ESDUpdate *esdU = (GF_ESDUpdate *)com;					m=0;					while ((imp_esd = (GF_ESD*)gf_list_enum(esdU->ESDescriptors, &m))) {						if (imp_esd->ESID == ES_ID) return imp_esd;					}				}					break;				}			}		}	}	return NULL;}static GF_Err gf_sm_encode_scene(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, u32 scene_type){	char *data;	Bool is_in_iod, delete_desc, first_scene_id;	u32 i, j, di, rate, init_offset, data_len, count, track, rap_delay, flags, rap_mode;	u64 last_rap, dur, time_slice, avg_rate, prev_dts;	GF_Err e;	GF_InitialObjectDescriptor *iod;	GF_AUContext *au;	GF_ISOSample *samp;	GF_StreamContext *sc;	GF_ESD *esd;	GF_BifsEncoder *bifs_enc;#ifndef GPAC_DISABLE_SVG	GF_LASeRCodec *lsr_enc;#endif	rap_mode = 0;	if (opts && opts->rap_freq) {		if (opts->flags & GF_SM_ENCODE_RAP_INBAND) rap_mode = 3;		else if (opts->flags & GF_SM_ENCODE_RAP_SHADOW) rap_mode = 2;

⌨️ 快捷键说明

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