static GF_Err gf_sm_live_encode_bifs_au(GF_BifsEngine *codec, u32 currentAUCount, GF_Err (*AUCallback)(void *, char *, u32 , u64) ) { GF_Err e; u32 j, size, count; char *data; GF_AUContext *au; if (!AUCallback) return GF_BAD_PARAM; e = GF_OK; count = gf_list_count(codec->sc->AUs); for (j=currentAUCount; j<count; j++) { au = (GF_AUContext *)gf_list_get(codec->sc->AUs, j); /*in case using XMT*/ if (au->timing_sec) au->timing = (u64) (au->timing_sec * codec->stream_ts_res); e = gf_bifs_encode_au(codec->bifsenc, codec->sc->ESID, au->commands, &data, &size); AUCallback(codec->calling_object, data, size, au->timing); free(data); data = NULL; if (e) break; } return e; }
static GF_Err gf_sm_live_encode_scene_au(GF_SceneEngine *seng, gf_seng_callback callback, Bool from_start) { GF_Err e; u32 i, j, size, count, nb_streams; char *data; GF_AUContext *au; if (!callback) return GF_BAD_PARAM; e = GF_OK; nb_streams = gf_list_count(seng->ctx->streams); for (i=0; i<nb_streams;i++) { GF_StreamContext *sc = gf_list_get(seng->ctx->streams, i); if (sc->streamType != GF_STREAM_SCENE) continue; count = gf_list_count(sc->AUs); j = from_start ? 0 : sc->current_au_count; for (; j<count; j++) { au = (GF_AUContext *)gf_list_get(sc->AUs, j); data = NULL; size = 0; /*in case using XMT*/ if (au->timing_sec) au->timing = (u64) (au->timing_sec * sc->timeScale); if (from_start && !j && !gf_sm_check_for_modif(seng, au)) continue; switch (sc->objectType) { #ifndef GPAC_DISABLE_BIFS_ENC case GPAC_OTI_SCENE_BIFS: case GPAC_OTI_SCENE_BIFS_V2: e = gf_bifs_encode_au(seng->bifsenc, sc->ESID, au->commands, &data, &size); break; #endif #ifndef GPAC_DISABLE_LASER case GPAC_OTI_SCENE_LASER: e = gf_laser_encode_au(seng->lsrenc, sc->ESID, au->commands, 0, &data, &size); break; #endif case GPAC_OTI_SCENE_DIMS: e = gf_seng_encode_dims_au(seng, sc->ESID, au->commands, &data, &size); break; default: GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("Cannot encode AU for Scene OTI %x\n", sc->objectType)); break; } callback(seng->calling_object, sc->ESID, data, size, au->timing); gf_free(data); data = NULL; if (e) break; } } return e; }
GF_EXPORT GF_Err gf_seng_encode_from_commands(GF_SceneEngine *seng, u16 ESID, Bool disable_aggregation, u32 time, GF_List *commands, gf_seng_callback callback) { GF_Err e; u32 size; char *data; GF_StreamContext *sc; u32 i, nb_streams; GF_AUContext *new_au; if (!callback) return GF_BAD_PARAM; if (!commands || !gf_list_count(commands)) return GF_BAD_PARAM; e = GF_OK; /* if the ESID is not provided we try to use the first scene stream */ sc = NULL; nb_streams = gf_list_count(seng->ctx->streams); for (i=0; i<nb_streams;i++) { GF_StreamContext *tmp_sc = gf_list_get(seng->ctx->streams, i); if (tmp_sc->streamType != GF_STREAM_SCENE) continue; sc = tmp_sc; if (!ESID) break; else if (sc->ESID == ESID) break; } if (!sc) return GF_BAD_PARAM; /* We need to create an empty AU for the parser to correctly parse a LASeR Command without SceneUnit */ new_au = gf_seng_create_new_au(sc, time); if (disable_aggregation) new_au->flags = GF_SM_AU_NOT_AGGREGATED; /* Removing the commands from the input list to avoid destruction and setting the RAP flag */ while (gf_list_count(commands)) { GF_Command *com = gf_list_get(commands, 0); gf_list_rem(commands, 0); switch (com->tag) { case GF_SG_SCENE_REPLACE: case GF_SG_LSR_NEW_SCENE: new_au->flags |= GF_SM_AU_RAP; break; } gf_list_add(new_au->commands, com); } data = NULL; size = 0; switch(sc->objectType) { #ifndef GPAC_DISABLE_BIFS_ENC case GPAC_OTI_SCENE_BIFS: case GPAC_OTI_SCENE_BIFS_V2: e = gf_bifs_encode_au(seng->bifsenc, ESID, new_au->commands, &data, &size); break; #endif #ifndef GPAC_DISABLE_LASER case GPAC_OTI_SCENE_LASER: e = gf_laser_encode_au(seng->lsrenc, ESID, new_au->commands, 0, &data, &size); break; #endif case GPAC_OTI_SCENE_DIMS: e = gf_seng_encode_dims_au(seng, ESID, new_au->commands, &data, &size); break; default: GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("Cannot encode commands for Scene OTI %x\n", sc->objectType)); break; } callback(seng->calling_object, ESID, data, size, 0); gf_free(data); return e; }