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

📄 encode_isom.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
		else rap_mode = 1;	}	e = GF_OK;	iod = (GF_InitialObjectDescriptor *) ctx->root_od;	/*if no iod check we only have one bifs*/	if (!iod) {		count = 0;		i=0;		while ((sc = (GF_StreamContext*)gf_list_enum(ctx->streams, &i))) {			if (sc->streamType == GF_STREAM_OD) count++;		}		if (!iod && count>1) return GF_NOT_SUPPORTED;	}	count = gf_list_count(ctx->streams);	sc = NULL;	flags = opts ? opts->flags : 0;	delete_desc = 0;	first_scene_id = 0;	esd = NULL;	/*configure streams*/	j=0;	for (i=0; i<count; i++) {		sc = (GF_StreamContext*)gf_list_get(ctx->streams, i);		esd = NULL;		if (sc->streamType != GF_STREAM_SCENE) continue;		/*NOT BIFS*/		if (!scene_type && (sc->objectType > 2) ) continue;		/*NOT LASeR*/		if (scene_type && (sc->objectType != 0x09) ) continue;		j++;	}	if (!j) {		GF_Node *n = gf_sg_get_root_node(ctx->scene_graph);		if (!n) return GF_OK;#ifndef GPAC_DISABLE_SVG		if ((scene_type==1) && (gf_node_get_tag(n)!=TAG_SVG_svg) ) return GF_OK;#endif		if ((scene_type==0) && (gf_node_get_tag(n)>GF_NODE_RANGE_LAST_X3D) ) return GF_OK;	}	bifs_enc = NULL;#ifndef GPAC_DISABLE_SVG	lsr_enc = NULL;#endif	if (!scene_type) {		bifs_enc = gf_bifs_encoder_new(ctx->scene_graph);		/*no streams defined, encode a RAP*/		if (!j) {			delete_desc = 0;			esd = NULL;			is_in_iod = 1;			goto force_scene_rap;		}	}		if (scene_type==1) {#ifndef GPAC_DISABLE_SVG		lsr_enc = gf_laser_encoder_new(ctx->scene_graph);		/*no streams defined, encode a RAP*/		if (!j) {			delete_desc = 0;			esd = NULL;			is_in_iod = 1;			goto force_scene_rap;		}#else		return GF_NOT_SUPPORTED;#endif	}	/*configure streams*/	for (i=0; i<count; i++) {		sc = (GF_StreamContext*)gf_list_get(ctx->streams, i);		esd = NULL;		if (sc->streamType != GF_STREAM_SCENE) continue;		/*NOT BIFS*/		if (!scene_type && (sc->objectType > 2) ) continue;		/*NOT LASeR*/		if (scene_type && (sc->objectType != 0x09) ) 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 && esd->decoderConfig->streamType == GF_STREAM_SCENE) {					if (!sc->ESID) sc->ESID = esd->ESID;					if (sc->ESID == esd->ESID) {						is_in_iod = 1;						break;					}				}				/*special BIFS direct import from NHNT*/				else if (gf_list_count(iod->ESDescriptors)==1) {					sc->ESID = esd->ESID;					is_in_iod = 1;					break;				}				esd = NULL;			}		}		if (!esd && sc->ESID) esd = gf_sm_locate_esd(ctx, sc->ESID);		au = NULL;		/*special BIFS direct import from NHNT*/		au = (GF_AUContext*)gf_list_get(sc->AUs, 0);		if (gf_list_count(sc->AUs) == 1) {			if (gf_list_count(au->commands) == 1) {				GF_Command *com = (GF_Command *)gf_list_get(au->commands, 0);				/*no root node, no protos (empty replace) - that's BIFS NHNT import*/				if ((com->tag == GF_SG_SCENE_REPLACE) && !com->node && !gf_list_count(com->new_proto_list))					au = NULL;			}		} 		/*sanity check: remove first command if it is REPLACE SCENE BY NULL*/		if (au && !au->timing && !au->timing_sec && (gf_list_count(au->commands) > 1)) {			GF_Command *com = (GF_Command *)gf_list_get(au->commands, 0);			if (com->tag==GF_SG_SCENE_REPLACE) {				if (!com->node && !gf_list_count(com->new_proto_list) ) {					gf_list_rem(au->commands, 0);					gf_sg_command_del(com);				}			}		}		if (!au && !esd->URLString) {			/*if not in IOD, the stream will be imported when encoding the OD stream*/			if (!is_in_iod) continue;			e = gf_sm_import_stream(ctx, mp4, esd, NULL);			if (e) goto exit;			gf_sm_finalize_mux(mp4, esd, 0);			gf_isom_add_track_to_root_od(mp4, gf_isom_get_track_by_id(mp4, esd->ESID));			continue;		}force_scene_rap:		if (!esd) {			delete_desc = 1;			esd = gf_odf_desc_esd_new(2);			gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo);			esd->decoderConfig->decoderSpecificInfo = NULL;			esd->ESID = sc ? sc->ESID : 1;			esd->decoderConfig->streamType = GF_STREAM_SCENE;		}				if (!esd->slConfig) esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);		if (sc && sc->timeScale) esd->slConfig->timestampResolution = sc->timeScale;		if (!esd->slConfig->timestampResolution) esd->slConfig->timestampResolution = 1000;		/*force scene dependencies (we cannot encode in 2 different scene contexts)*/		if (!esd->dependsOnESID) {			if (!first_scene_id) {				esd->dependsOnESID = 0;				first_scene_id = esd->ESID;			} else {				esd->dependsOnESID = first_scene_id;			}		}		if (!esd->decoderConfig) esd->decoderConfig = (GF_DecoderConfig*)gf_odf_desc_new(GF_ODF_DCD_TAG);		esd->decoderConfig->streamType = GF_STREAM_SCENE;		/*create track*/		track = gf_isom_new_track(mp4, sc ? sc->ESID : 1, GF_ISOM_MEDIA_SCENE, esd->slConfig->timestampResolution);		if (!track) {			e = gf_isom_last_error(mp4);			goto exit;		}		gf_isom_set_track_enabled(mp4, track, 1);		if (sc) {			if (!sc->ESID) sc->ESID = gf_isom_get_track_id(mp4, track);			esd->ESID = sc->ESID;		}		/*BIFS setup*/		if (!scene_type) {			GF_BIFSConfig *bcfg;			Bool delete_bcfg = 0;			if (!esd->decoderConfig->decoderSpecificInfo) {				bcfg = (GF_BIFSConfig*)gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG);				delete_bcfg = 1;			} else if (esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_BIFS_CFG_TAG) {				bcfg = (GF_BIFSConfig *)esd->decoderConfig->decoderSpecificInfo;			} else {				bcfg = gf_odf_get_bifs_config(esd->decoderConfig->decoderSpecificInfo, esd->decoderConfig->objectTypeIndication);				delete_bcfg = 1;			}			/*update NodeIDbits and co*/			/*nodeID bits shall include NULL node*/			if (!bcfg->nodeIDbits || (bcfg->nodeIDbits<gf_get_bit_size(ctx->max_node_id)) )				bcfg->nodeIDbits = gf_get_bit_size(ctx->max_node_id);			if (!bcfg->routeIDbits || (bcfg->routeIDbits != gf_get_bit_size(ctx->max_route_id)) )				bcfg->routeIDbits = gf_get_bit_size(ctx->max_route_id);			if (!bcfg->protoIDbits || (bcfg->protoIDbits != gf_get_bit_size(ctx->max_proto_id)) )				bcfg->protoIDbits = gf_get_bit_size(ctx->max_proto_id);			if (!bcfg->elementaryMasks) {				bcfg->pixelMetrics = ctx->is_pixel_metrics;				bcfg->pixelWidth = ctx->scene_width;				bcfg->pixelHeight = ctx->scene_height;			}			/*this is for safety, otherwise some players may not understand NULL node*/			if (!bcfg->nodeIDbits) bcfg->nodeIDbits = 1;			gf_bifs_encoder_new_stream(bifs_enc, esd->ESID, bcfg, (flags & GF_SM_ENCODE_USE_NAMES) ? 1 : 0, 0);			if (delete_bcfg) gf_odf_desc_del((GF_Descriptor *)bcfg);			/*create final BIFS config*/			if (esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo);			esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG);			gf_bifs_encoder_get_config(bifs_enc, esd->ESID, &data, &data_len);			esd->decoderConfig->decoderSpecificInfo->data = data;			esd->decoderConfig->decoderSpecificInfo->dataLength = data_len;			esd->decoderConfig->objectTypeIndication = gf_bifs_encoder_get_version(bifs_enc, esd->ESID);				} 		/*LASeR setup*/#ifndef GPAC_DISABLE_SVG		if (scene_type==1) {			GF_LASERConfig lsrcfg;			if (!esd->decoderConfig->decoderSpecificInfo) {				memset(&lsrcfg, 0, sizeof(GF_LASERConfig));				lsrcfg.tag = GF_ODF_LASER_CFG_TAG;			} else if (esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_LASER_CFG_TAG) {				memcpy(&lsrcfg, (GF_LASERConfig *)esd->decoderConfig->decoderSpecificInfo, sizeof(GF_LASERConfig));			} else {				gf_odf_get_laser_config(esd->decoderConfig->decoderSpecificInfo, &lsrcfg);			}			/*create final BIFS config*/			if (esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo);			esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG);			/*this is for safety, otherwise some players may not understand NULL node*/			if (flags & GF_SM_ENCODE_USE_NAMES) lsrcfg.force_string_ids = 1;			/*override of default*/			if (opts) {				if (opts->resolution) lsrcfg.resolution = opts->resolution;				if (opts->coord_bits) lsrcfg.coord_bits = opts->coord_bits;				/*by default use 2 extra bits for scale*/				lsrcfg.scale_bits_minus_coord_bits = opts->scale_bits ? opts->scale_bits : 2;			}			gf_laser_encoder_new_stream(lsr_enc, esd->ESID , &lsrcfg);			/*get final config*/			gf_laser_encoder_get_config(lsr_enc, esd->ESID, &data, &data_len);			esd->decoderConfig->decoderSpecificInfo->data = data;			esd->decoderConfig->decoderSpecificInfo->dataLength = data_len;			esd->decoderConfig->objectTypeIndication = 0x09;		}#endif		/*create stream description*/		gf_isom_new_mpeg4_description(mp4, track, esd, NULL, NULL, &di);		if (is_in_iod) {			gf_isom_add_track_to_root_od(mp4, track);			if (ctx->scene_width && ctx->scene_height)				gf_isom_set_visual_info(mp4, track, di, ctx->scene_width, ctx->scene_height);		}		if (esd->URLString) continue;		if (!sc) {			samp = gf_isom_sample_new();			samp->IsRAP = 1;					if (bifs_enc)				e = gf_bifs_encoder_get_rap(bifs_enc, &samp->data, &samp->dataLength);#ifndef GPAC_DISABLE_SVG			else if (lsr_enc)				e = gf_laser_encoder_get_rap(lsr_enc, &samp->data, &samp->dataLength);#endif			if (!e && samp->dataLength) e = gf_isom_add_sample(mp4, track, di, samp);			gf_isom_sample_del(&samp);			goto exit;		}		dur = 0;		avg_rate = 0;		esd->decoderConfig->bufferSizeDB = 0;		esd->decoderConfig->maxBitrate = 0;		rate = 0;		time_slice = 0;		last_rap = 0;		rap_delay = 0;		if (opts) rap_delay = opts->rap_freq * esd->slConfig->timestampResolution / 1000;		prev_dts = 0;		init_offset = 0;		j=0;		while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) {			samp = gf_isom_sample_new();			/*time in sec conversion*/			if (au->timing_sec) au->timing = (u64) (au->timing_sec * esd->slConfig->timestampResolution);			if (j==1) init_offset = (u32) au->timing;			samp->DTS = au->timing - init_offset;			samp->IsRAP = au->is_rap;			if (samp->IsRAP) last_rap = au->timing;			/*inband RAP insertion*/			if (rap_mode==3) {				if (samp->DTS - last_rap < rap_delay) {					/*first encode command*/					if (bifs_enc)						e = gf_bifs_encode_au(bifs_enc, sc->ESID, au->commands, &samp->data, &samp->dataLength);#ifndef GPAC_DISABLE_SVG					else if (lsr_enc)						e = gf_laser_encode_au(lsr_enc, sc->ESID, au->commands, 0, &samp->data, &samp->dataLength);#endif					/*and apply commands*/					e = gf_sg_command_apply_list(ctx->scene_graph, au->commands, 0);				} else {					/*first apply commands*/					e = gf_sg_command_apply_list(ctx->scene_graph, au->commands, 0);					/*then get RAP*/					if (bifs_enc)						e = gf_bifs_encoder_get_rap(bifs_enc, &samp->data, &samp->dataLength);#ifndef GPAC_DISABLE_SVG					else if (lsr_enc)						e = gf_laser_encoder_get_rap(lsr_enc, &samp->data, &samp->dataLength);#endif					samp->IsRAP = 1;					last_rap = samp->DTS;				}			} else {				if (bifs_enc)					e = gf_bifs_encode_au(bifs_enc, sc->ESID, au->commands, &samp->data, &samp->dataLength);#ifndef GPAC_DISABLE_SVG				else if (lsr_enc)					e = gf_laser_encode_au(lsr_enc, sc->ESID, au->commands, 0, &samp->data, &samp->dataLength);#endif			}			/*carousel generation*/			if (!e && (rap_mode == 1)) {				if (samp->DTS - last_rap > rap_delay) {					GF_ISOSample *car_samp = gf_isom_sample_new();					u64 r_dts = samp->DTS;									/*then get RAP*/					if (bifs_enc)						e = gf_bifs_encoder_get_rap(bifs_enc, &car_samp->data, &car_samp->dataLength);#ifndef GPAC_DISABLE_SVG					else if (lsr_enc)						e = gf_laser_encoder_get_rap(lsr_enc, &car_samp->data, &car_samp->dataLength);#endif					car_samp->IsRAP = 2;										while (1) {						car_samp->DTS = last_rap+rap_delay;						if (car_samp->DTS==prev_dts) car_samp->DTS++;						e = gf_isom_add_sample(mp4, track, di, car_samp);						if (e) break;						last_rap+=rap_delay;						if (last_rap + rap_delay >= r_dts) break;					}					gf_isom_sample_del(&car_samp);				}				if (!e && samp->dataLength) e = gf_isom_add_sample(mp4, track, di, samp);				/*accumulate commmands*/				e = gf_sg_command_apply_list(ctx->scene_graph, au->commands, 0);			} else {				/*if no commands don't add the AU*/				if (!e && samp->dataLength) e = gf_isom_add_sample(mp4, track, di, samp);			}			dur = au->timing;			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;			}								prev_dts = samp->DTS;			gf_isom_sample_del(&samp);			if (e) goto 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;		}

⌨️ 快捷键说明

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