Пример #1
0
static GF_Err gf_sm_setup_bifsenc(GF_SceneEngine *seng, GF_StreamContext *sc, GF_ESD *esd)
{
	char *data;
	u32 data_len;
	u32	nbb;
	Bool encode_names, delete_bcfg;
	GF_BIFSConfig *bcfg;

	if (!esd->decoderConfig || (esd->decoderConfig->streamType != GF_STREAM_SCENE)) return GF_BAD_PARAM;

	if (!seng->bifsenc)
		seng->bifsenc = gf_bifs_encoder_new(seng->ctx->scene_graph);

	delete_bcfg = 0;
	/*inputctx is not properly setup, do it*/
	if (!esd->decoderConfig->decoderSpecificInfo) {
		bcfg = (GF_BIFSConfig*)gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG);
		bcfg->pixelMetrics = seng->ctx->is_pixel_metrics;
		bcfg->pixelWidth = seng->ctx->scene_width;
		bcfg->pixelHeight = seng->ctx->scene_height;
		delete_bcfg = 1;
	}
	/*regular case*/
	else if (esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_BIFS_CFG_TAG) {
		bcfg = (GF_BIFSConfig *)esd->decoderConfig->decoderSpecificInfo;
	}
	/*happens when loading from MP4 in which case BIFSc is not decoded*/
	else {
		bcfg = gf_odf_get_bifs_config(esd->decoderConfig->decoderSpecificInfo, esd->decoderConfig->objectTypeIndication);
		delete_bcfg = 1;
	}

	/*NO CHANGE TO BIFSC otherwise the generated update will not match the input context
	The only case we modify the bifs config is when XXXBits is not specified*/
	nbb = gf_get_bit_size(seng->ctx->max_node_id);
	if (!bcfg->nodeIDbits) bcfg->nodeIDbits = nbb;
	else if (bcfg->nodeIDbits<nbb) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.NodeIDBits too small (%d bits vs %d nodes)\n", bcfg->nodeIDbits, seng->ctx->max_node_id));
	}
	nbb = gf_get_bit_size(seng->ctx->max_route_id);
	if (!bcfg->routeIDbits) bcfg->routeIDbits = nbb;
	else if (bcfg->routeIDbits<nbb) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.RouteIDBits too small (%d bits vs %d routes)\n", bcfg->routeIDbits, seng->ctx->max_route_id));
	}
	nbb = gf_get_bit_size(seng->ctx->max_proto_id);
	if (!bcfg->protoIDbits) bcfg->protoIDbits=nbb;
	else if (bcfg->protoIDbits<nbb) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.ProtoIDBits too small (%d bits vs %d protos)\n", bcfg->protoIDbits, seng->ctx->max_proto_id));
	}

	/*this is the real pb, not stored in cfg or file level, set at EACH replaceScene*/
	encode_names = 0;

	/* The BIFS Config that is passed here should be the BIFSConfig from the IOD */
	gf_bifs_encoder_new_stream(seng->bifsenc, esd->ESID, bcfg, encode_names, 0);
	if (delete_bcfg) gf_odf_desc_del((GF_Descriptor *)bcfg);

	gf_bifs_encoder_get_config(seng->bifsenc, esd->ESID, &data, &data_len);

	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);
	esd->decoderConfig->decoderSpecificInfo->data = data;
	esd->decoderConfig->decoderSpecificInfo->dataLength = data_len;
		
	sc->dec_cfg = gf_malloc(sizeof(char)*data_len);
	memcpy(sc->dec_cfg, data, data_len);
	sc->dec_cfg_len = data_len;

	esd->decoderConfig->objectTypeIndication = gf_bifs_encoder_get_version(seng->bifsenc, esd->ESID);		

	return GF_OK;
}
Пример #2
0
static GF_Err gf_sm_live_setup(GF_BifsEngine *codec)
{
	GF_Err e;
	char *data;
	u32 data_len;
	GF_InitialObjectDescriptor *iod;
	u32	i, j, count, nbb;
	GF_ESD *esd;
	Bool is_in_iod, delete_desc, encode_names, delete_bcfg;
	GF_BIFSConfig *bcfg;

	e = GF_OK;

	iod = (GF_InitialObjectDescriptor *) codec->ctx->root_od;
	/*if no iod check we only have one bifs*/
	if (!iod) {
		count = 0;
		i=0;
		while ((codec->sc = (GF_StreamContext*)gf_list_enum(codec->ctx->streams, &i))) {
			if (codec->sc->streamType == GF_STREAM_OD) count++;
			codec->sc = NULL;
		}
		if (!iod && count>1) return GF_NOT_SUPPORTED;
	}

	codec->sc = NULL;
	count = gf_list_count(codec->ctx->streams);
	i=0;
	while ((codec->sc = (GF_StreamContext*)gf_list_enum(codec->ctx->streams, &i))) {
		if (codec->sc->streamType == GF_STREAM_SCENE) break;
	}
	if (!codec->sc) return GF_NOT_SUPPORTED;
	if (!codec->sc->ESID) codec->sc->ESID = 1;

	codec->bifsenc = gf_bifs_encoder_new(codec->ctx->scene_graph);

	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 (!codec->sc->ESID) codec->sc->ESID = esd->ESID;
				if (codec->sc->ESID == esd->ESID) {
					is_in_iod = 1;
					break;
				}
			}
			/*special BIFS direct import from NHNT*/
			else if (gf_list_count(iod->ESDescriptors)==1) {
				codec->sc->ESID = esd->ESID;
				is_in_iod = 1;
				break;
			}
			esd = NULL;
		}
	}

	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 = codec->sc->ESID;
		esd->decoderConfig->streamType = GF_STREAM_SCENE;
	}

	delete_bcfg = 0;

	/*should NOT happen (means inputctx is not properly setup)*/
	if (!esd->decoderConfig->decoderSpecificInfo) {
		bcfg = (GF_BIFSConfig*)gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG);
		bcfg->pixelMetrics = codec->ctx->is_pixel_metrics;
		bcfg->pixelWidth = codec->ctx->scene_width;
		bcfg->pixelHeight = codec->ctx->scene_height;
		delete_bcfg = 1;
	}
	/*regular retrieve from ctx*/
	else if (esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_BIFS_CFG_TAG) {
		bcfg = (GF_BIFSConfig *)esd->decoderConfig->decoderSpecificInfo;
	}
	/*should not happen either (unless loading from MP4 in which case BIFSc is not decoded)*/
	else {
		bcfg = gf_odf_get_bifs_config(esd->decoderConfig->decoderSpecificInfo, esd->decoderConfig->objectTypeIndication);
		delete_bcfg = 1;
	}
	/*NO CHANGE TO BIFSC otherwise the generated update will not match the input context, UNLESS NO NbBits
	were specified*/
	nbb = gf_get_bit_size(codec->ctx->max_node_id);
	if (!bcfg->nodeIDbits) bcfg->nodeIDbits = nbb;
	else if (bcfg->nodeIDbits<nbb) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.NodeIDBits too small (%d bits vs %d nodes)\n", bcfg->nodeIDbits, codec->ctx->max_node_id));
	}
	nbb = gf_get_bit_size(codec->ctx->max_route_id);
	if (!bcfg->routeIDbits) bcfg->routeIDbits = nbb;
	else if (bcfg->routeIDbits<nbb) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.RouteIDBits too small (%d bits vs %d routes)\n", bcfg->routeIDbits, codec->ctx->max_route_id));
	}
	nbb = gf_get_bit_size(codec->ctx->max_proto_id);
	if (!bcfg->protoIDbits) bcfg->protoIDbits=nbb;
	else if (bcfg->protoIDbits<nbb) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.ProtoIDBits too small (%d bits vs %d protos)\n", bcfg->protoIDbits, codec->ctx->max_proto_id));
	}

	/*this is the real pb, not stored in cfg or file level, set at EACH replaceScene*/
	encode_names = 0;

	/* The BIFS Config that is passed here should be the BIFSConfig from the IOD */
	gf_bifs_encoder_new_stream(codec->bifsenc, codec->sc->ESID, bcfg, encode_names, 0);
	if (delete_bcfg) gf_odf_desc_del((GF_Descriptor *)bcfg);

	if (!esd->slConfig) esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);
	if (codec->sc->timeScale) esd->slConfig->timestampResolution = codec->sc->timeScale;
	if (!esd->slConfig->timestampResolution) esd->slConfig->timestampResolution = 1000;

	esd->ESID = codec->sc->ESID;
	gf_bifs_encoder_get_config(codec->bifsenc, codec->sc->ESID, &data, &data_len);

	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);
	esd->decoderConfig->decoderSpecificInfo->data = data;
	esd->decoderConfig->decoderSpecificInfo->dataLength = data_len;
	
	codec->stream_ts_res = esd->slConfig->timestampResolution;
	memcpy(codec->encoded_bifs_config, data, data_len);
	codec->encoded_bifs_config_size = data_len;

	esd->decoderConfig->objectTypeIndication = gf_bifs_encoder_get_version(codec->bifsenc, codec->sc->ESID);		
	return e;
}