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

📄 encode_isom.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
		gf_isom_change_mpeg4_description(mp4, track, 1, esd);		/*sync shadow generation*/		if (rap_mode==2) {			GF_AUContext *au;			u32 au_count = gf_list_count(sc->AUs);			last_rap = 0;			for (j=0; j<au_count; j++) {				au = (GF_AUContext *)gf_list_get(sc->AUs, j);				e = gf_sg_command_apply_list(ctx->scene_graph, au->commands, 0);				if (!j) continue;				/*force a RAP shadow on last sample*/				if ((au->timing - last_rap < rap_delay) && (j+1<au_count) ) continue;				samp = gf_isom_sample_new();				last_rap = samp->DTS = au->timing - init_offset;				samp->IsRAP = 1;				/*RAP generation*/				if (bifs_enc)					e = gf_bifs_encoder_get_rap(bifs_enc, &samp->data, &samp->dataLength);				if (!e) e = gf_isom_add_sample_shadow(mp4, track, samp);				gf_isom_sample_del(&samp);				if (e) goto exit;			}		}		/*if offset add edit list*/		gf_sm_finalize_mux(mp4, esd, (u32) init_offset);		gf_isom_set_last_sample_duration(mp4, track, 0);		if (delete_desc) {			gf_odf_desc_del((GF_Descriptor *) esd);			esd = NULL;		}	}	/*to do - proper PL setup according to node used...*/	gf_isom_set_pl_indication(mp4, GF_ISOM_PL_SCENE, 1);	gf_isom_set_pl_indication(mp4, GF_ISOM_PL_GRAPHICS, 1);exit:	if (bifs_enc) gf_bifs_encoder_del(bifs_enc);#ifndef GPAC_DISABLE_SVG	if (lsr_enc) gf_laser_encoder_del(lsr_enc);#endif	if (esd && delete_desc) gf_odf_desc_del((GF_Descriptor *) esd);	return e;}static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *mediaSource, GF_SMEncodeOptions *opts){	u32 i, j, n, m, rap_delay;	GF_ESD *esd;	GF_StreamContext *sc;	GF_AUContext *au;	u32 count, track, rate, di;	u64 dur, time_slice, init_offset, avg_rate, last_rap, last_not_shadow;	Bool is_in_iod, delete_desc, rap_inband, rap_shadow;	GF_ISOSample *samp;	GF_Err e;	GF_ODCodec *codec, *rap_codec;	GF_InitialObjectDescriptor *iod;	gf_isom_set_pl_indication(mp4, GF_ISOM_PL_OD, 0xFE);	iod = (GF_InitialObjectDescriptor *) ctx->root_od;	count = 0;	i=0;	while ((sc = (GF_StreamContext*)gf_list_enum(ctx->streams, &i))) {		if (sc->streamType == GF_STREAM_OD) count++;	}	/*no OD stream, nothing to do*/	if (!count) return GF_OK;	if (!iod && count>1) return GF_NOT_SUPPORTED;	rap_inband = rap_shadow = 0;	rap_delay = 0;	if (opts && opts->rap_freq) {		if (opts->flags & GF_SM_ENCODE_RAP_INBAND) {			rap_inband = 1;		} else {			rap_shadow = 1;		}	}	esd = NULL;	codec = rap_codec = NULL;	delete_desc = 0;	i=0;	while ((sc = (GF_StreamContext*)gf_list_enum(ctx->streams, &i))){		if (sc->streamType != GF_STREAM_OD) continue;		delete_desc = 0;		esd = NULL;		is_in_iod = 1;		if (iod) {			is_in_iod = 0;			j=0;			while ((esd = (GF_ESD*)gf_list_enum(iod->ESDescriptors, &j))) {				if (esd->decoderConfig->streamType != GF_STREAM_OD){					esd = NULL;					continue;				}				if (!sc->ESID) sc->ESID = esd->ESID;				if (sc->ESID == esd->ESID) {					is_in_iod = 1;					break;				}			}		}		if (!esd) esd = gf_sm_locate_esd(ctx, sc->ESID);		if (!esd) {			delete_desc = 1;			esd = gf_odf_desc_esd_new(2);			esd->ESID = sc->ESID;			esd->decoderConfig->objectTypeIndication = 1;			esd->decoderConfig->streamType = GF_STREAM_OD;		}		/*create OD track*/		if (!esd->slConfig) esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);		if (sc->timeScale) esd->slConfig->timestampResolution = sc->timeScale;		if (!esd->slConfig->timestampResolution) esd->slConfig->timestampResolution = 1000;		track = gf_isom_new_track(mp4, sc->ESID, GF_ISOM_MEDIA_OD, esd->slConfig->timestampResolution);		if (!sc->ESID) sc->ESID = gf_isom_get_track_id(mp4, track);		gf_isom_set_track_enabled(mp4, track, 1);		/*no DSI required*/		/*create stream description*/		gf_isom_new_mpeg4_description(mp4, track, esd, NULL, NULL, &di);		/*add to root OD*/		if (is_in_iod) gf_isom_add_track_to_root_od(mp4, track);		codec = gf_odf_codec_new();		if (rap_inband || rap_shadow) {			rap_codec = gf_odf_codec_new();			rap_delay = opts->rap_freq * esd->slConfig->timestampResolution / 1000;		}				dur = avg_rate = 0;		esd->decoderConfig->bufferSizeDB = 0;		esd->decoderConfig->maxBitrate = 0;		rate = 0;		time_slice = 0;		init_offset = 0;		last_rap = 0;		rap_delay = 0;		last_not_shadow = 0;		if (opts) rap_delay = opts->rap_freq * esd->slConfig->timestampResolution / 1000;		/*encode all samples and perform import - FIXME this is destructive...*/		j=0;		while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) {						while (gf_list_count(au->commands) ) {				GF_ODCom *com = (GF_ODCom *) gf_list_get(au->commands, 0);				gf_list_rem(au->commands, 0);				/*only updates commandes need to be parsed for import*/				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))) {							switch (imp_esd->tag) {							case GF_ODF_ESD_TAG:								e = gf_sm_import_stream(ctx, mp4, imp_esd, mediaSource);								if (e) {									GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] cannot import stream %d (error %s)\n", imp_esd->ESID, gf_error_to_string(e)));									gf_odf_com_del(&com);									goto err_exit;								}								gf_sm_finalize_mux(mp4, imp_esd, 0);								break;							case GF_ODF_ESD_REF_TAG:							case GF_ODF_ESD_INC_TAG:								break;							default:								GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[ISO File Encode] Invalid descriptor in OD%d.ESDescr\n", od->objectDescriptorID));								e = GF_BAD_PARAM;								goto err_exit;								break;							}						}					}				}					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))) {						switch (imp_esd->tag) {						case GF_ODF_ESD_TAG:							e = gf_sm_import_stream(ctx, mp4, imp_esd, mediaSource);							if (e) {								GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] cannot import stream %d (error %s)\n", imp_esd->ESID, gf_error_to_string(e)));								gf_odf_com_del(&com);								goto err_exit;							}							gf_sm_finalize_mux(mp4, imp_esd, 0);							break;						case GF_ODF_ESD_REF_TAG:						case GF_ODF_ESD_INC_TAG:							break;						default:							GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[ISO File Encode] Invalid descriptor in ESDUpdate (OD %d)\n", esdU->ODID));							e = GF_BAD_PARAM;							goto err_exit;							break;						}					}				}					break;				}				/*add to codec*/				gf_odf_codec_add_com(codec, com);				if (rap_codec) {					e = gf_odf_codec_apply_com(rap_codec, com);					if (e) goto err_exit;				}			}			e = gf_odf_codec_encode(codec, 1);			if (e) goto err_exit;			/*time in sec conversion*/			if (au->timing_sec) au->timing = (u64) (au->timing_sec * esd->slConfig->timestampResolution);			if (j==1) init_offset = au->timing;			samp = gf_isom_sample_new();			samp->DTS = au->timing - init_offset;			samp->IsRAP = au->is_rap;			last_not_shadow = samp->DTS;			if (rap_inband && (samp->DTS - last_rap >= rap_delay)) {				last_rap = samp->DTS;				e = gf_odf_codec_encode(rap_codec, 0);				if (e) goto err_exit;				e = gf_odf_codec_get_au(rap_codec, &samp->data, &samp->dataLength);				samp->IsRAP = 1;			} else {				e = gf_odf_codec_get_au(codec, &samp->data, &samp->dataLength);			}			if (!e) e = gf_isom_add_sample(mp4, track, di, samp);			dur = au->timing - init_offset;			avg_rate += samp->dataLength;			rate += samp->dataLength;			if (esd->decoderConfig->bufferSizeDB<samp->dataLength) esd->decoderConfig->bufferSizeDB = samp->dataLength;			if (samp->DTS - time_slice > esd->slConfig->timestampResolution) {				if (esd->decoderConfig->maxBitrate < rate) esd->decoderConfig->maxBitrate = rate;				rate = 0;				time_slice = samp->DTS;			}			if (rap_shadow && (samp->DTS - last_rap >= rap_delay)) {				last_rap = samp->DTS;				e = gf_odf_codec_encode(rap_codec, 0);				if (e) goto err_exit;				if (samp->data) free(samp->data);				samp->data = NULL;				samp->dataLength = 0;				e = gf_odf_codec_get_au(rap_codec, &samp->data, &samp->dataLength);				if (e) goto err_exit;				samp->IsRAP = 1;				e = gf_isom_add_sample_shadow(mp4, track, samp);				if (e) goto err_exit;				last_not_shadow = 0;			}			gf_isom_sample_del(&samp);			if (e) goto err_exit;		}		if (dur) {			esd->decoderConfig->avgBitrate = (u32) (avg_rate * esd->slConfig->timestampResolution * 8 / dur);			esd->decoderConfig->maxBitrate *= 8;		} else {			esd->decoderConfig->avgBitrate = 0;			esd->decoderConfig->maxBitrate = 0;		}		gf_isom_change_mpeg4_description(mp4, track, 1, esd);		gf_sm_finalize_mux(mp4, esd, (u32) init_offset);		if (delete_desc) {			gf_odf_desc_del((GF_Descriptor *) esd);			esd = NULL;		}		esd = NULL;		gf_isom_set_last_sample_duration(mp4, track, 0);		if (rap_codec) {			if (last_not_shadow) {				samp = gf_isom_sample_new();				samp->DTS = last_not_shadow;				samp->IsRAP = 1;				e = gf_odf_codec_encode(rap_codec, 0);				if (!e) e = gf_odf_codec_get_au(rap_codec, &samp->data, &samp->dataLength);				if (!e) e = gf_isom_add_sample_shadow(mp4, track, samp);				if (e) goto err_exit;				gf_isom_sample_del(&samp);			}			gf_odf_codec_del(rap_codec);			rap_codec = NULL;		}	}	e = gf_isom_set_pl_indication(mp4, GF_ISOM_PL_OD, 1);	err_exit:	if (codec) gf_odf_codec_del(codec);	if (rap_codec) gf_odf_codec_del(rap_codec);	if (esd && delete_desc) gf_odf_desc_del((GF_Descriptor *) esd);	return e;}GF_EXPORTGF_Err gf_sm_encode_to_file(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEncodeOptions *opts){	u32 i, count;	GF_Descriptor *desc;	GF_Err e;	if (!ctx->scene_graph) return GF_BAD_PARAM;	if (ctx->root_od && (ctx->root_od->tag != GF_ODF_IOD_TAG) && (ctx->root_od->tag != GF_ODF_OD_TAG)) return GF_BAD_PARAM;	/*import specials, that is input remapping to BIFS*/	e = gf_sm_import_specials(ctx);	if (e) return e;	/*encode BIFS*/	e = gf_sm_encode_scene(ctx, mp4, opts, 0);	if (e) return e;	/*encode LASeR*/	e = gf_sm_encode_scene(ctx, mp4, opts, 1);	if (e) return e;	/*then encode OD to setup all streams*/	e = gf_sm_encode_od(ctx, mp4, opts ? opts->mediaSource : NULL, opts);	if (e) return e;	/*store iod*/	if (ctx->root_od) {		gf_isom_set_root_od_id(mp4, ctx->root_od->objectDescriptorID);		if (ctx->root_od->URLString) gf_isom_set_root_od_url(mp4, ctx->root_od->URLString);		count = gf_list_count(ctx->root_od->extensionDescriptors);		for (i=0; i<count; i++) {			desc = (GF_Descriptor *) gf_list_get(ctx->root_od->extensionDescriptors, i);			gf_isom_add_desc_to_root_od(mp4, desc);		}		count = gf_list_count(ctx->root_od->IPMP_Descriptors);		for (i=0; i<count; i++) {			desc = (GF_Descriptor *) gf_list_get(ctx->root_od->IPMP_Descriptors, i);			gf_isom_add_desc_to_root_od(mp4, desc);		}		count = gf_list_count(ctx->root_od->OCIDescriptors);		for (i=0; i<count; i++) {			desc = (GF_Descriptor *) gf_list_get(ctx->root_od->OCIDescriptors, i);			gf_isom_add_desc_to_root_od(mp4, desc);		}		if (ctx->root_od->tag==GF_ODF_IOD_TAG) {			GF_InitialObjectDescriptor *iod = (GF_InitialObjectDescriptor*)ctx->root_od;			if (iod->IPMPToolList) gf_isom_add_desc_to_root_od(mp4, (GF_Descriptor *) iod->IPMPToolList);		}		/*we assume all ESs described in bt/xmt input are used*/	}	/*set PLs*/	if (ctx->root_od && ctx->root_od->tag==GF_ODF_IOD_TAG) {		GF_InitialObjectDescriptor *iod =  (GF_InitialObjectDescriptor *)ctx->root_od;		gf_isom_set_pl_indication(mp4, GF_ISOM_PL_SCENE, iod->scene_profileAndLevel);		gf_isom_set_pl_indication(mp4, GF_ISOM_PL_GRAPHICS, iod->graphics_profileAndLevel);	} else {		gf_isom_set_pl_indication(mp4, GF_ISOM_PL_SCENE, 0xFE);		gf_isom_set_pl_indication(mp4, GF_ISOM_PL_GRAPHICS, 0xFE);	}	return GF_OK;}#endif

⌨️ 快捷键说明

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