GF_EXPORT GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_offset) { GF_Err e; GF_CommandField *inf; GF_FieldInfo field; GF_Node *def, *node; void *slot_ptr; if (!com || !graph) return GF_BAD_PARAM; e = GF_OK; switch (com->tag) { case GF_SG_SCENE_REPLACE: /*unregister root*/ gf_node_unregister(graph->RootNode, NULL); /*remove all protos and routes*/ while (gf_list_count(graph->routes_to_activate)) gf_list_rem(graph->routes_to_activate, 0); /*destroy all routes*/ while (gf_list_count(graph->Routes)) { GF_Route *r = (GF_Route *)gf_list_get(graph->Routes, 0); /*this will unregister the route from the graph, so don't delete the chain entry*/ gf_sg_route_del(r); } /*destroy all proto*/ while (gf_list_count(graph->protos)) { GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0); /*this will unregister the proto from the graph, so don't delete the chain entry*/ gf_sg_proto_del(p); } /*DO NOT TOUCH node registry*/ /*DO NOT TOUCH UNREGISTERED PROTOS*/ /*move all protos in graph*/ while (gf_list_count(com->new_proto_list)) { GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0); gf_list_rem(com->new_proto_list, 0); gf_list_del_item(graph->unregistered_protos, p); gf_list_add(graph->protos, p); } /*assign new root (no need to register/unregister)*/ graph->RootNode = com->node; com->node = NULL; break; case GF_SG_NODE_REPLACE: if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); e = gf_node_replace(com->node, inf->new_node, 0); if (inf->new_node) gf_node_register(inf->new_node, NULL); break; case GF_SG_MULTIPLE_REPLACE: case GF_SG_FIELD_REPLACE: { u32 j; GF_ChildNodeItem *list, *cur, *prev; j=0; while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &j))) { e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; switch (field.fieldType) { case GF_SG_VRML_SFNODE: { node = *((GF_Node **) field.far_ptr); e = gf_node_unregister(node, com->node); *((GF_Node **) field.far_ptr) = inf->new_node; if (!e) gf_node_register(inf->new_node, com->node); break; } case GF_SG_VRML_MFNODE: gf_node_unregister_children(com->node, * ((GF_ChildNodeItem **) field.far_ptr)); * ((GF_ChildNodeItem **) field.far_ptr) = NULL; list = * ((GF_ChildNodeItem **) inf->field_ptr); prev=NULL; while (list) { cur = malloc(sizeof(GF_ChildNodeItem)); cur->next = NULL; cur->node = list->node; if (prev) { prev->next = cur; } else { * ((GF_ChildNodeItem **) field.far_ptr) = cur; } gf_node_register(list->node, com->node); prev = cur; list = list->next; } break; default: /*this is a regular field, reset it and clone - we cannot switch pointers since the original fields are NOT pointers*/ if (!gf_sg_vrml_is_sf_field(field.fieldType)) { e = gf_sg_vrml_mf_reset(field.far_ptr, field.fieldType); } if (e) return e; gf_sg_vrml_field_copy(field.far_ptr, inf->field_ptr, field.fieldType); if (field.fieldType==GF_SG_VRML_SFTIME) *(SFTime *)field.far_ptr = *(SFTime *)field.far_ptr + time_offset; break; } SG_CheckFieldChange(com->node, &field); } break; } case GF_SG_MULTIPLE_INDEXED_REPLACE: case GF_SG_INDEXED_REPLACE: { u32 sftype, i=0; while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &i))) { e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; /*if MFNode remove the child and set new node*/ if (field.fieldType == GF_SG_VRML_MFNODE) { /*we must remove the node before in case the new node uses the same ID (not forbidden) and this command removes the last instance of the node with the same ID*/ gf_node_replace_child(com->node, (GF_ChildNodeItem**) field.far_ptr, inf->pos, inf->new_node); if (inf->new_node) gf_node_register(inf->new_node, NULL); } /*erase the field item*/ else { if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) { inf->pos = ((GenMFField *)field.far_ptr)->count - 1; /*may happen with text and default value*/ if (inf->pos < 0) { inf->pos = 0; gf_sg_vrml_mf_alloc(field.far_ptr, field.fieldType, 1); } } e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & slot_ptr, inf->pos); if (e) return e; sftype = gf_sg_vrml_get_sf_type(field.fieldType); gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype); /*note we don't add time offset, since there's no MFTime*/ } SG_CheckFieldChange(com->node, &field); } break; } case GF_SG_ROUTE_REPLACE: { GF_Route *r; char *name; r = gf_sg_route_find(graph, com->RouteID); def = gf_sg_find_node(graph, com->fromNodeID); node = gf_sg_find_node(graph, com->toNodeID); if (!node || !def) return GF_SG_UNKNOWN_NODE; name = NULL; if (r) { name = r->name; r->name = NULL; gf_sg_route_del(r); } r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex); gf_sg_route_set_id(r, com->RouteID); if (name) { gf_sg_route_set_name(r, name); free(name); } break; } case GF_SG_NODE_DELETE_EX: case GF_SG_NODE_DELETE: { if (com->node) gf_node_replace(com->node, NULL, (com->tag==GF_SG_NODE_DELETE_EX) ? 1 : 0); break; } case GF_SG_ROUTE_DELETE: { return gf_sg_route_del_by_id(graph, com->RouteID); } case GF_SG_INDEXED_DELETE: { if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; /*then we need special handling in case of a node*/ if (gf_sg_vrml_get_sf_type(field.fieldType) == GF_SG_VRML_SFNODE) { e = gf_node_replace_child(com->node, (GF_ChildNodeItem **) field.far_ptr, inf->pos, NULL); } else { if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) { inf->pos = ((GenMFField *)field.far_ptr)->count - 1; } /*this is a regular MFField, just remove the item (realloc)*/ e = gf_sg_vrml_mf_remove(field.far_ptr, field.fieldType, inf->pos); } /*deletion -> node has changed*/ if (!e) SG_CheckFieldChange(com->node, &field); break; } case GF_SG_NODE_INSERT: { if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); e = gf_node_insert_child(com->node, inf->new_node, inf->pos); if (!e) gf_node_register(inf->new_node, com->node); if (!e) gf_node_event_out(com->node, inf->fieldIndex); if (!e) gf_node_changed(com->node, NULL); break; } case GF_SG_ROUTE_INSERT: { GF_Route *r; def = gf_sg_find_node(graph, com->fromNodeID); node = gf_sg_find_node(graph, com->toNodeID); if (!node || !def) return GF_SG_UNKNOWN_NODE; r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex); if (com->RouteID) gf_sg_route_set_id(r, com->RouteID); if (com->def_name) { gf_sg_route_set_name(r, com->def_name); free(com->def_name); com->def_name = NULL; } break; } case GF_SG_INDEXED_INSERT: { u32 sftype; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; /*rescale the MFField and parse the SFField*/ if (field.fieldType != GF_SG_VRML_MFNODE) { if (inf->pos == -1) { e = gf_sg_vrml_mf_append(field.far_ptr, field.fieldType, & slot_ptr); } else { e = gf_sg_vrml_mf_insert(field.far_ptr, field.fieldType, & slot_ptr, inf->pos); } if (e) return e; sftype = gf_sg_vrml_get_sf_type(field.fieldType); gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype); } else { if (inf->new_node) { if (inf->pos == -1) { gf_node_list_add_child( (GF_ChildNodeItem **) field.far_ptr, inf->new_node); } else { gf_node_list_insert_child((GF_ChildNodeItem **) field.far_ptr, inf->new_node, inf->pos); } gf_node_register(inf->new_node, com->node); } } if (!e) SG_CheckFieldChange(com->node, &field); break; } case GF_SG_PROTO_INSERT: /*destroy all proto*/ while (gf_list_count(com->new_proto_list)) { GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0); gf_list_rem(com->new_proto_list, 0); gf_list_del_item(graph->unregistered_protos, p); gf_list_add(graph->protos, p); } return GF_OK; case GF_SG_PROTO_DELETE: { u32 i; for (i=0; i<com->del_proto_list_size; i++) { /*note this will check for unregistered protos, but since IDs are unique we are sure we will not destroy an unregistered one*/ GF_Proto *proto = gf_sg_find_proto(graph, com->del_proto_list[i], NULL); if (proto) gf_sg_proto_del(proto); } } return GF_OK; case GF_SG_PROTO_DELETE_ALL: /*destroy all proto*/ while (gf_list_count(graph->protos)) { GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0); gf_list_rem(graph->protos, 0); /*this will unregister the proto from the graph, so don't delete the chain entry*/ gf_sg_proto_del(p); } /*DO NOT TOUCH UNREGISTERED PROTOS*/ return GF_OK; /*only used by BIFS*/ case GF_SG_GLOBAL_QUANTIZER: return GF_OK; #ifndef GPAC_DISABLE_SVG /*laser commands*/ case GF_SG_LSR_NEW_SCENE: /*DO NOT TOUCH node registry*/ /*assign new root (no need to register/unregister)*/ graph->RootNode = com->node; com->node = NULL; break; case GF_SG_LSR_DELETE: if (!com->node) return GF_NON_COMPLIANT_BITSTREAM; if (!gf_list_count(com->command_fields)) { gf_node_replace(com->node, NULL, 0); gf_node_deactivate(com->node); return GF_OK; } inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); node = gf_node_list_get_child(((SVG_Element *)com->node)->children, inf->pos); if (node) { e = gf_node_replace_child(com->node, &((SVG_Element *)com->node)->children, inf->pos, NULL); gf_node_deactivate(node); } break; case GF_SG_LSR_INSERT: inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); if (!com->node || !inf) return GF_NON_COMPLIANT_BITSTREAM; if (inf->new_node) { if (inf->pos<0) gf_node_list_add_child(& ((SVG_Element *)com->node)->children, inf->new_node); else gf_node_list_insert_child(& ((SVG_Element *)com->node)->children, inf->new_node, inf->pos); gf_node_register(inf->new_node, com->node); gf_node_activate(inf->new_node); gf_node_changed(com->node, NULL); } else { /*NOT SUPPORTED*/ GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[LASeR] VALUE INSERTION NOT SUPPORTED\n")); } break; case GF_SG_LSR_ADD: case GF_SG_LSR_REPLACE: inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); if (!com->node || !inf) return GF_NON_COMPLIANT_BITSTREAM; if (inf->new_node) { if (inf->pos<0) { /*if fieldIndex (eg attributeName) is set, this is children replacement*/ if (inf->fieldIndex>0) { gf_node_unregister_children_deactivate(com->node, ((SVG_Element *)com->node)->children); ((SVG_Element *)com->node)->children = NULL; gf_node_list_add_child(& ((SVG_Element *)com->node)->children, inf->new_node); gf_node_register(inf->new_node, com->node); gf_node_activate(inf->new_node); } else { e = gf_node_replace(com->node, inf->new_node, 0); gf_node_activate(inf->new_node); } } else { node = gf_node_list_get_child( ((SVG_Element *)com->node)->children, inf->pos); gf_node_replace_child(com->node, & ((SVG_Element *)com->node)->children, inf->pos, inf->new_node); gf_node_register(inf->new_node, com->node); if (node) gf_node_deactivate(node); gf_node_activate(inf->new_node); } /*signal node modif*/ gf_node_changed(com->node, NULL); return e; } else if (inf->node_list) { GF_ChildNodeItem *child, *cur, *prev; gf_node_unregister_children_deactivate(com->node, ((SVG_Element *)com->node)->children); ((SVG_Element *)com->node)->children = NULL; prev = NULL; child = inf->node_list; while (child) { cur = (GF_ChildNodeItem*)malloc(sizeof(GF_ChildNodeItem)); cur->next = NULL; cur->node = child->node; gf_node_register(child->node, com->node); gf_node_activate(child->node); if (prev) prev->next = cur; else ((SVG_Element *)com->node)->children = cur; prev = cur; child = child->next; } /*signal node modif*/ gf_node_changed(com->node, NULL); return GF_OK; } /*attribute modif*/ else if (inf->field_ptr) { GF_FieldInfo a, b; if (inf->fieldIndex==(u32) -2) { GF_Point2D scale, translate; Fixed rotate; GF_Matrix2D *dest; gf_node_get_field_by_name(com->node, "transform", &a); dest = (GF_Matrix2D*)a.far_ptr; if (com->tag==GF_SG_LSR_REPLACE) { if (gf_mx2d_decompose(dest, &scale, &rotate, &translate)) { gf_mx2d_init(*dest); if (inf->fieldType==SVG_TRANSFORM_SCALE) scale = *(GF_Point2D *)inf->field_ptr; else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) translate = *(GF_Point2D *)inf->field_ptr; else if (inf->fieldType==SVG_TRANSFORM_ROTATE) rotate = ((SVG_Point_Angle*)inf->field_ptr)->angle; gf_mx2d_add_scale(dest, scale.x, scale.y); gf_mx2d_add_rotation(dest, 0, 0, rotate); gf_mx2d_add_translation(dest, translate.x, translate.y); } } else { GF_Point2D *pt = (GF_Point2D *)inf->field_ptr; if (inf->fieldType==SVG_TRANSFORM_SCALE) gf_mx2d_add_scale(dest, pt->x, pt->y); else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) gf_mx2d_add_translation(dest, pt->x, pt->y); else if (inf->fieldType == SVG_TRANSFORM_ROTATE) gf_mx2d_add_rotation(dest, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle); } } else { if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==SVG_String_datatype)) { char *str = *(SVG_String*)inf->field_ptr; if (com->tag == GF_SG_LSR_REPLACE) { GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; if (t && (t->sgprivate->tag==TAG_DOMText)) { if (t->textContent) free(t->textContent); t->textContent = NULL; if (str) t->textContent = strdup(str); } } else { if (str) gf_dom_add_text_node(com->node, strdup(str)); } } else if ((inf->fieldIndex==TAG_LSR_ATT_scale) || (inf->fieldIndex==TAG_LSR_ATT_translation) || (inf->fieldIndex==TAG_LSR_ATT_rotation) ) { SVG_Transform *mx; gf_svg_get_attribute_by_tag(com->node, TAG_SVG_ATT_transform, 1, 0, &a); mx = a.far_ptr; if (com->tag == GF_SG_LSR_REPLACE) { GF_Point2D scale, translate; SVG_Point_Angle rotate; if (gf_mx2d_decompose(&mx->mat, &scale, &rotate.angle, &translate)) { gf_mx2d_init(mx->mat); if (inf->fieldIndex==TAG_LSR_ATT_scale) scale = *(GF_Point2D *)inf->field_ptr; else if (inf->fieldIndex==TAG_LSR_ATT_translation) translate = *(GF_Point2D *)inf->field_ptr; else if (inf->fieldIndex==TAG_LSR_ATT_rotation) rotate = *(SVG_Point_Angle*)inf->field_ptr; gf_mx2d_add_scale(&mx->mat, scale.x, scale.y); gf_mx2d_add_rotation(&mx->mat, 0, 0, rotate.angle); gf_mx2d_add_translation(&mx->mat, translate.x, translate.y); } } else { if (inf->fieldIndex==TAG_LSR_ATT_scale) gf_mx2d_add_scale(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y); if (inf->fieldIndex==TAG_LSR_ATT_translation) gf_mx2d_add_translation(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y); if (inf->fieldIndex==TAG_LSR_ATT_rotation) gf_mx2d_add_rotation(&mx->mat, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle); } } else if (gf_svg_get_attribute_by_tag(com->node, inf->fieldIndex, 1, 0, &a) == GF_OK) { b = a; b.far_ptr = inf->field_ptr; if (com->tag == GF_SG_LSR_REPLACE) { gf_svg_attributes_copy(&a, &b, 0); } else { gf_svg_attributes_add(&a, &b, &a, 0); } } b = a; b.far_ptr = inf->field_ptr; } /*signal node modif*/ gf_node_changed(com->node, &a); } else if (com->fromNodeID) { GF_FieldInfo a, b; GF_Node *fromNode = gf_sg_find_node(graph, com->fromNodeID); if (!fromNode) return GF_NON_COMPLIANT_BITSTREAM; if (gf_node_get_field(fromNode, com->fromFieldIndex, &b) != GF_OK) return GF_NON_COMPLIANT_BITSTREAM; if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==SVG_String_datatype)) { char *str = *(SVG_String*)inf->field_ptr; if (com->tag == GF_SG_LSR_REPLACE) { GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; if (t && (t->sgprivate->tag==TAG_DOMText)) { if (t->textContent) free(t->textContent); t->textContent = NULL; if (str) t->textContent = strdup(str); } } else { if (str) gf_dom_add_text_node(com->node, strdup(str)); } } else { gf_node_get_field(com->node, inf->fieldIndex, &a); if (com->tag == GF_SG_LSR_REPLACE) { e = gf_svg_attributes_copy(&a, &b, 0); } else { e = gf_svg_attributes_add(&a, &b, &a, 0); } } gf_node_changed(com->node, &a); return e; } else { return GF_NON_COMPLIANT_BITSTREAM; } break; case GF_SG_LSR_ACTIVATE: gf_node_activate(com->node); break; case GF_SG_LSR_DEACTIVATE: gf_node_deactivate(com->node); gf_node_changed(com->node, NULL); break; #endif default: return GF_NOT_SUPPORTED; } if (e) return e; if (com->scripts_to_load) { while (gf_list_count(com->scripts_to_load)) { GF_Node *script = (GF_Node *)gf_list_get(com->scripts_to_load, 0); gf_list_rem(com->scripts_to_load, 0); gf_sg_script_load(script); } gf_list_del(com->scripts_to_load); com->scripts_to_load = NULL; } return GF_OK; }
GF_EXPORT GF_Err gf_isom_3gp_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_3GPConfig *cfg, char *URLname, char *URNname, u32 *outDescriptionIndex) { GF_TrackBox *trak; GF_Err e; u32 dataRefIndex; u32 cfg_type; e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM; switch (cfg->type) { case GF_ISOM_SUBTYPE_3GP_AMR: case GF_ISOM_SUBTYPE_3GP_AMR_WB: if (trak->Media->handler->handlerType!=GF_ISOM_MEDIA_AUDIO) return GF_BAD_PARAM; cfg_type = GF_ISOM_BOX_TYPE_DAMR; break; case GF_ISOM_SUBTYPE_3GP_EVRC: if (trak->Media->handler->handlerType!=GF_ISOM_MEDIA_AUDIO) return GF_BAD_PARAM; cfg_type = GF_ISOM_BOX_TYPE_DEVC; break; case GF_ISOM_SUBTYPE_3GP_QCELP: if (trak->Media->handler->handlerType!=GF_ISOM_MEDIA_AUDIO) return GF_BAD_PARAM; cfg_type = GF_ISOM_BOX_TYPE_DQCP; break; case GF_ISOM_SUBTYPE_3GP_SMV: if (trak->Media->handler->handlerType!=GF_ISOM_MEDIA_AUDIO) return GF_BAD_PARAM; cfg_type = GF_ISOM_BOX_TYPE_DSMV; break; case GF_ISOM_SUBTYPE_3GP_H263: if (trak->Media->handler->handlerType!=GF_ISOM_MEDIA_VISUAL) return GF_BAD_PARAM; cfg_type = GF_ISOM_BOX_TYPE_D263; break; case 0: return GF_BAD_PARAM; default: return GF_NOT_SUPPORTED; } //get or create the data ref e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex); if (e) return e; if (!dataRefIndex) { e = Media_CreateDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex); if (e) return e; } trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); switch (cfg->type) { case GF_ISOM_SUBTYPE_3GP_AMR: case GF_ISOM_SUBTYPE_3GP_AMR_WB: case GF_ISOM_SUBTYPE_3GP_EVRC: case GF_ISOM_SUBTYPE_3GP_QCELP: case GF_ISOM_SUBTYPE_3GP_SMV: { GF_3GPPAudioSampleEntryBox *entry = (GF_3GPPAudioSampleEntryBox *) gf_isom_box_new(cfg->type); if (!entry) return GF_OUT_OF_MEM; entry->info = (GF_3GPPConfigBox *) gf_isom_box_new(cfg_type); if (!entry->info) { gf_isom_box_del((GF_Box *) entry); return GF_OUT_OF_MEM; } memcpy(&entry->info->cfg, cfg, sizeof(GF_3GPConfig)); entry->samplerate_hi = trak->Media->mediaHeader->timeScale; entry->dataReferenceIndex = dataRefIndex; e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, entry); *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes); } break; case GF_ISOM_SUBTYPE_3GP_H263: { GF_3GPPVisualSampleEntryBox *entry = (GF_3GPPVisualSampleEntryBox *) gf_isom_box_new(cfg->type); if (!entry) return GF_OUT_OF_MEM; entry->info = (GF_3GPPConfigBox *) gf_isom_box_new(cfg_type); if (!entry->info) { gf_isom_box_del((GF_Box *) entry); return GF_OUT_OF_MEM; } memcpy(&entry->info->cfg, cfg, sizeof(GF_3GPConfig)); entry->dataReferenceIndex = dataRefIndex; e = gf_list_add(trak->Media->information->sampleTable->SampleDescription->other_boxes, entry); *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->other_boxes); } break; } return e; }
static void TraverseViewport(GF_Node *node, void *rs, Bool is_destroy) { Fixed sx, sy, w, h, tx, ty; #ifndef GPAC_DISABLE_3D GF_Matrix mx; #endif GF_Matrix2D mat; GF_Rect rc, rc_bckup; ViewStack *st = (ViewStack *) gf_node_get_private(node); M_Viewport *vp = (M_Viewport *) node; GF_TraverseState *tr_state = (GF_TraverseState *)rs; if (is_destroy) { DestroyViewStack(node); return; } #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d>1) return; #endif /*first traverse, bound if needed*/ if (gf_list_find(tr_state->viewpoints, node) < 0) { gf_list_add(tr_state->viewpoints, node); assert(gf_list_find(st->reg_stacks, tr_state->viewpoints)==-1); gf_list_add(st->reg_stacks, tr_state->viewpoints); if (gf_list_get(tr_state->viewpoints, 0) == vp) { if (!vp->isBound) Bindable_SetIsBound(node, 1); } else { if (gf_inline_is_default_viewpoint(node)) Bindable_SetSetBindEx(node, 1, tr_state->viewpoints); } VPCHANGED(tr_state->visual->compositor); /*in any case don't draw the first time (since the viewport could have been declared last)*/ gf_sc_invalidate(tr_state->visual->compositor, NULL); return; } if (tr_state->traversing_mode != TRAVERSE_BINDABLE) return; if (!vp->isBound) return; if (gf_list_get(tr_state->viewpoints, 0) != vp) return; #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d) { w = tr_state->bbox.max_edge.x - tr_state->bbox.min_edge.x; h = tr_state->bbox.max_edge.y - tr_state->bbox.min_edge.y; } else #endif { w = tr_state->bounds.width; h = tr_state->bounds.height; } if (!w || !h) return; /*if no parent this is the main viewport, don't update if not changed*/ // if (!tr_state->is_layer && !gf_node_dirty_get(node)) return; gf_node_dirty_clear(node, 0); gf_mx2d_init(mat); gf_mx2d_add_translation(&mat, vp->position.x, vp->position.y); gf_mx2d_add_rotation(&mat, 0, 0, vp->orientation); //compute scaling ratio sx = (vp->size.x>=0) ? vp->size.x : w; sy = (vp->size.y>=0) ? vp->size.y : h; rc = gf_rect_center(sx, sy); rc_bckup = rc; switch (vp->fit) { /*covers all area and respect aspect ratio*/ case 2: if (gf_divfix(rc.width, w) > gf_divfix(rc.height, h)) { rc.width = gf_muldiv(rc.width, h, rc.height); rc.height = h; } else { rc.height = gf_muldiv(rc.height , w, rc.width); rc.width = w; } break; /*fits inside the area and respect AR*/ case 1: if (gf_divfix(rc.width, w)> gf_divfix(rc.height, h)) { rc.height = gf_muldiv(rc.height, w, rc.width); rc.width = w; } else { rc.width = gf_muldiv(rc.width, h, rc.height); rc.height = h; } break; /*fit entirely: nothing to change*/ case 0: rc.width = w; rc.height = h; break; default: return; } sx = gf_divfix(rc.width, rc_bckup.width); sy = gf_divfix(rc.height, rc_bckup.height); /*viewport on root visual, remove compositor scale*/ if (!tr_state->is_layer && (tr_state->visual->compositor->visual==tr_state->visual) ) { sx = gf_divfix(sx, tr_state->visual->compositor->scale_x); sy = gf_divfix(sy, tr_state->visual->compositor->scale_y); } rc.x = - rc.width/2; rc.y = rc.height/2; tx = ty = 0; if (vp->fit && vp->alignment.count) { /*left alignment*/ if (vp->alignment.vals[0] == -1) tx = rc.width/2 - w/2; else if (vp->alignment.vals[0] == 1) tx = w/2 - rc.width/2; if (vp->alignment.count>1) { /*top-alignment*/ if (vp->alignment.vals[1]==-1) ty = rc.height/2 - h/2; else if (vp->alignment.vals[1]==1) ty = h/2 - rc.height/2; } } gf_mx2d_init(mat); if (tr_state->pixel_metrics) { gf_mx2d_add_scale(&mat, sx, sy); } else { /*if we are not in pixelMetrics, undo the meterMetrics->pixelMetrics transformation*/ gf_mx2d_add_scale(&mat, gf_divfix(sx, tr_state->min_hsize), gf_divfix(sy, tr_state->min_hsize) ); } gf_mx2d_add_translation(&mat, tx, ty); gf_mx2d_add_translation(&mat, -gf_mulfix(vp->position.x,sx), -gf_mulfix(vp->position.y,sy) ); gf_mx2d_add_rotation(&mat, 0, 0, vp->orientation); tr_state->bounds = rc; tr_state->bounds.x += tx; tr_state->bounds.y += ty; #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d) { /*in layers directly modify the model matrix*/ if (tr_state->is_layer) { gf_mx_from_mx2d(&mx, &mat); gf_mx_add_matrix(&tr_state->model_matrix, &mx); } /*otherwise add to camera viewport matrix*/ else { gf_mx_from_mx2d(&tr_state->camera->viewport, &mat); tr_state->camera->flags = (CAM_HAS_VIEWPORT | CAM_IS_DIRTY); } } else #endif gf_mx2d_pre_multiply(&tr_state->transform, &mat); }
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_BIFS_ENC 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; }
int dc_read_configuration(CmdData *cmd_data) { const char *opt; u32 i; GF_Config *conf = cmd_data->conf; u32 sec_count = gf_cfg_get_section_count(conf); for (i=0; i<sec_count; i++) { const char *section_name = gf_cfg_get_section_name(conf, i); const char *section_type = gf_cfg_get_key(conf, section_name, "type"); if (strcmp(section_type, "video") == 0) { VideoDataConf *video_data_conf; GF_SAFEALLOC(video_data_conf, VideoDataConf); strcpy(video_data_conf->filename, section_name); opt = gf_cfg_get_key(conf, section_name, "codec"); if (!opt) opt = DEFAULT_VIDEO_CODEC; strcpy(video_data_conf->codec, opt); opt = gf_cfg_get_key(conf, section_name, "bitrate"); video_data_conf->bitrate = opt ? atoi(opt) : DEFAULT_VIDEO_BITRATE; opt = gf_cfg_get_key(conf, section_name, "framerate"); video_data_conf->framerate = opt ? atoi(opt) : DEFAULT_VIDEO_FRAMERATE; opt = gf_cfg_get_key(conf, section_name, "height"); video_data_conf->height = opt ? atoi(opt) : DEFAULT_VIDEO_HEIGHT; opt = gf_cfg_get_key(conf, section_name, "width"); video_data_conf->width = opt ? atoi(opt) : DEFAULT_VIDEO_WIDTH; opt = gf_cfg_get_key(conf, section_name, "crop_x"); video_data_conf->crop_x = opt ? atoi(opt) : 0; opt = gf_cfg_get_key(conf, section_name, "crop_y"); video_data_conf->crop_x = opt ? atoi(opt) : 0; opt = gf_cfg_get_key(conf, section_name, "custom"); video_data_conf->custom = opt ? gf_strdup(opt) : NULL; gf_list_add(cmd_data->video_lst, (void *) video_data_conf); } else if (strcmp(section_type, "audio") == 0) { AudioDataConf *audio_data_conf; GF_SAFEALLOC(audio_data_conf, AudioDataConf); strcpy(audio_data_conf->filename, section_name); opt = gf_cfg_get_key(conf, section_name, "codec"); if (!opt) opt = DEFAULT_AUDIO_CODEC; strcpy(audio_data_conf->codec, opt); opt = gf_cfg_get_key(conf, section_name, "bitrate"); audio_data_conf->bitrate = opt ? atoi(opt) : DEFAULT_AUDIO_BITRATE; opt = gf_cfg_get_key(conf, section_name, "samplerate"); audio_data_conf->samplerate = opt ? atoi(opt) : DEFAULT_AUDIO_SAMPLERATE; opt = gf_cfg_get_key(conf, section_name, "channels"); audio_data_conf->channels = opt ? atoi(opt) : DEFAULT_AUDIO_CHANNELS; opt = gf_cfg_get_key(conf, section_name, "custom"); audio_data_conf->custom = opt ? gf_strdup(opt) : NULL; gf_list_add(cmd_data->audio_lst, (void *) audio_data_conf); } else { fprintf(stderr, "Configuration file: type %s is not supported.\n", section_type); } } fprintf(stdout, "\33[34m\33[1m"); fprintf(stdout, "Configurations:\n"); for (i=0; i<gf_list_count(cmd_data->video_lst); i++) { VideoDataConf *video_data_conf = gf_list_get(cmd_data->video_lst, i); fprintf(stdout, " id:%s\tres:%dx%d\tvbr:%d\n", video_data_conf->filename, video_data_conf->width, video_data_conf->height, video_data_conf->bitrate/*, video_data_conf->framerate, video_data_conf->codec*/); } for (i=0; i<gf_list_count(cmd_data->audio_lst); i++) { AudioDataConf *audio_data_conf = gf_list_get(cmd_data->audio_lst, i); fprintf(stdout, " id:%s\tabr:%d\n", audio_data_conf->filename, audio_data_conf->bitrate/*, audio_data_conf->samplerate, audio_data_conf->channels,audio_data_conf->codec*/); } fprintf(stdout, "\33[0m"); fflush(stdout); return 0; }
void InitKeySensor(GF_Scene *scene, GF_Node *node) { gf_node_set_private(node, scene->root_od->term); gf_node_set_callback_function(node, DestroyKeySensor); gf_list_add(scene->root_od->term->x3d_sensors, node); }
// Rewrite the good dependancies when an OD AU is extracted from the file GF_Err Media_RewriteODFrame(GF_MediaBox *mdia, GF_ISOSample *sample) { GF_Err e; GF_ODCodec *ODdecode; GF_ODCodec *ODencode; GF_ODCom *com; //the commands we proceed GF_ESDUpdate *esdU, *esdU2; GF_ESDRemove *esdR, *esdR2; GF_ODUpdate *odU, *odU2; //the desc they contain GF_ObjectDescriptor *od; GF_IsomObjectDescriptor *isom_od; GF_ESD *esd; GF_ES_ID_Ref *ref; GF_Descriptor *desc; GF_TrackReferenceTypeBox *mpod; u32 i, j, skipped; if (!mdia || !sample || !sample->data || !sample->dataLength) return GF_BAD_PARAM; mpod = NULL; e = Track_FindRef(mdia->mediaTrack, GF_ISOM_BOX_TYPE_MPOD, &mpod); if (e) return e; //no references, nothing to do... if (!mpod) return GF_OK; ODdecode = gf_odf_codec_new(); if (!ODdecode) return GF_OUT_OF_MEM; ODencode = gf_odf_codec_new(); if (!ODencode) { gf_odf_codec_del(ODdecode); return GF_OUT_OF_MEM; } e = gf_odf_codec_set_au(ODdecode, sample->data, sample->dataLength); if (e) goto err_exit; e = gf_odf_codec_decode(ODdecode); if (e) goto err_exit; while (1) { com = gf_odf_codec_get_com(ODdecode); if (!com) break; //we only need to rewrite commands with ESDs inside: ESDUpdate and ODUpdate switch (com->tag) { case GF_ODF_OD_UPDATE_TAG: odU = (GF_ODUpdate *) com; odU2 = (GF_ODUpdate *) gf_odf_com_new(GF_ODF_OD_UPDATE_TAG); i=0; while ((desc = (GF_Descriptor*)gf_list_enum(odU->objectDescriptors, &i))) { switch (desc->tag) { case GF_ODF_OD_TAG: case GF_ODF_ISOM_OD_TAG: //IOD can be used in OD streams case GF_ODF_ISOM_IOD_TAG: break; default: return GF_ISOM_INVALID_FILE; } e = gf_odf_desc_copy(desc, (GF_Descriptor **)&isom_od); if (e) goto err_exit; //create our OD... if (desc->tag == GF_ODF_ISOM_IOD_TAG) { od = (GF_ObjectDescriptor *) gf_malloc(sizeof(GF_InitialObjectDescriptor)); } else { od = (GF_ObjectDescriptor *) gf_malloc(sizeof(GF_ObjectDescriptor)); } if (!od) { e = GF_OUT_OF_MEM; goto err_exit; } od->ESDescriptors = gf_list_new(); //and duplicate... od->objectDescriptorID = isom_od->objectDescriptorID; od->tag = GF_ODF_OD_TAG; od->URLString = isom_od->URLString; isom_od->URLString = NULL; od->extensionDescriptors = isom_od->extensionDescriptors; isom_od->extensionDescriptors = NULL; od->IPMP_Descriptors = isom_od->IPMP_Descriptors; isom_od->IPMP_Descriptors = NULL; od->OCIDescriptors = isom_od->OCIDescriptors; isom_od->OCIDescriptors = NULL; //init as IOD if (isom_od->tag == GF_ODF_ISOM_IOD_TAG) { ((GF_InitialObjectDescriptor *)od)->audio_profileAndLevel = ((GF_IsomInitialObjectDescriptor *)isom_od)->audio_profileAndLevel; ((GF_InitialObjectDescriptor *)od)->inlineProfileFlag = ((GF_IsomInitialObjectDescriptor *)isom_od)->inlineProfileFlag; ((GF_InitialObjectDescriptor *)od)->graphics_profileAndLevel = ((GF_IsomInitialObjectDescriptor *)isom_od)->graphics_profileAndLevel; ((GF_InitialObjectDescriptor *)od)->OD_profileAndLevel = ((GF_IsomInitialObjectDescriptor *)isom_od)->OD_profileAndLevel; ((GF_InitialObjectDescriptor *)od)->scene_profileAndLevel = ((GF_IsomInitialObjectDescriptor *)isom_od)->scene_profileAndLevel; ((GF_InitialObjectDescriptor *)od)->visual_profileAndLevel = ((GF_IsomInitialObjectDescriptor *)isom_od)->visual_profileAndLevel; ((GF_InitialObjectDescriptor *)od)->IPMPToolList = ((GF_IsomInitialObjectDescriptor *)isom_od)->IPMPToolList; ((GF_IsomInitialObjectDescriptor *)isom_od)->IPMPToolList = NULL; } //then rewrite the ESDesc j=0; while ((ref = (GF_ES_ID_Ref*)gf_list_enum(isom_od->ES_ID_RefDescriptors, &j))){ //if the ref index is not valid, skip this desc... if (!mpod->trackIDs || gf_isom_get_track_from_id(mdia->mediaTrack->moov, mpod->trackIDs[ref->trackRef - 1]) == NULL) continue; //OK, get the esd e = GetESDForTime(mdia->mediaTrack->moov, mpod->trackIDs[ref->trackRef - 1], sample->DTS, &esd); if (!e) e = gf_odf_desc_add_desc((GF_Descriptor *) od, (GF_Descriptor *) esd); if (e) { gf_odf_desc_del((GF_Descriptor *)od); gf_odf_com_del((GF_ODCom **)&odU2); gf_odf_desc_del((GF_Descriptor *)isom_od); gf_odf_com_del((GF_ODCom **)&odU); goto err_exit; } } //delete our desc gf_odf_desc_del((GF_Descriptor *)isom_od); gf_list_add(odU2->objectDescriptors, od); } //clean a bit gf_odf_com_del((GF_ODCom **)&odU); gf_odf_codec_add_com(ODencode, (GF_ODCom *)odU2); break; case GF_ODF_ESD_UPDATE_TAG: esdU = (GF_ESDUpdate *) com; esdU2 = (GF_ESDUpdate *) gf_odf_com_new(GF_ODF_ESD_UPDATE_TAG); esdU2->ODID = esdU->ODID; i=0; while ((ref = (GF_ES_ID_Ref*)gf_list_enum(esdU->ESDescriptors, &i))) { //if the ref index is not valid, skip this desc... if (gf_isom_get_track_from_id(mdia->mediaTrack->moov, mpod->trackIDs[ref->trackRef - 1]) == NULL) continue; //OK, get the esd e = GetESDForTime(mdia->mediaTrack->moov, mpod->trackIDs[ref->trackRef - 1], sample->DTS, &esd); if (e) goto err_exit; gf_list_add(esdU2->ESDescriptors, esd); } gf_odf_com_del((GF_ODCom **)&esdU); gf_odf_codec_add_com(ODencode, (GF_ODCom *)esdU2); break; //brand new case: the ESRemove follows the same principle according to the spec... case GF_ODF_ESD_REMOVE_REF_TAG: //both commands have the same structure, only the tags change esdR = (GF_ESDRemove *) com; esdR2 = (GF_ESDRemove *) gf_odf_com_new(GF_ODF_ESD_REMOVE_TAG); esdR2->ODID = esdR->ODID; esdR2->NbESDs = esdR->NbESDs; //alloc our stuff esdR2->ES_ID = (unsigned short*)gf_malloc(sizeof(u32) * esdR->NbESDs); if (!esdR2->ES_ID) { e = GF_OUT_OF_MEM; goto err_exit; } skipped = 0; //get the ES_ID in the mpod indicated in the ES_ID[] for (i = 0; i < esdR->NbESDs; i++) { //if the ref index is not valid, remove this desc... if (gf_isom_get_track_from_id(mdia->mediaTrack->moov, mpod->trackIDs[esdR->ES_ID[i] - 1]) == NULL) { skipped ++; } else { //the command in the file has the ref index of the trackID in the mpod esdR2->ES_ID[i - skipped] = mpod->trackIDs[esdR->ES_ID[i] - 1]; } } //gf_realloc... if (skipped && (skipped != esdR2->NbESDs) ) { esdR2->NbESDs -= skipped; esdR2->ES_ID = (unsigned short*)gf_realloc(esdR2->ES_ID, sizeof(u32) * esdR2->NbESDs); } gf_odf_com_del((GF_ODCom **)&esdR); gf_odf_codec_add_com(ODencode, (GF_ODCom *)esdR2); break; default: e = gf_odf_codec_add_com(ODencode, com); if (e) goto err_exit; } } //encode our new AU e = gf_odf_codec_encode(ODencode, 1); if (e) goto err_exit; //and set the buffer in the sample gf_free(sample->data); sample->data = NULL; sample->dataLength = 0; e = gf_odf_codec_get_au(ODencode, &sample->data, &sample->dataLength); err_exit: gf_odf_codec_del(ODdecode); gf_odf_codec_del(ODencode); return e; }
GF_SceneGraph *gf_inline_get_proto_lib(void *_is, MFURL *lib_url) { GF_ProtoLink *pl; u32 i; GF_Scene *scene = (GF_Scene *) _is; if (!scene || !lib_url->count) return NULL; if (gf_inline_is_hardcoded_proto(lib_url, scene->root_od->term->user->config)) return GF_SG_INTERNAL_PROTO; i=0; while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i))) { if (!pl->mo) continue; if (gf_mo_get_od_id(pl->url) != GF_MEDIA_EXTERNAL_ID) { if (gf_mo_get_od_id(pl->url) == gf_mo_get_od_id(lib_url)) { if (!pl->mo->odm || !pl->mo->odm->subscene) return NULL; return pl->mo->odm->subscene->graph; } } } /*for string URL based protos, recursively check until top if the proto lib is not already present*/ if (lib_url->vals[0].url) { GF_Scene *check_scene = scene; while (check_scene) { i=0; while ((pl = (GF_ProtoLink*)gf_list_enum(check_scene->extern_protos, &i))) { char *url1, *url2; Bool ok; if (!pl->mo) continue; if (gf_mo_get_od_id(pl->url) != GF_MEDIA_EXTERNAL_ID) continue; /*not the same url*/ if (!gf_mo_is_same_url(pl->mo, lib_url, NULL, 0)) continue; /*check the url path is the same*/ url1 = gf_url_concatenate(pl->mo->odm->net_service->url, lib_url->vals[0].url); url2 = gf_url_concatenate(scene->root_od->net_service->url, lib_url->vals[0].url); ok = 0; if (url1 && url2 && !strcmp(url1, url2)) ok=1; if (url1) gf_free(url1); if (url2) gf_free(url2); if (!ok) continue; if (!pl->mo->odm || !pl->mo->odm->subscene) return NULL; return pl->mo->odm->subscene->graph; } check_scene = check_scene->root_od->parentscene; } } /*not found, let's try to load it*/ if (!lib_url || !lib_url->count) return NULL; /*internal, don't waste ressources*/ if (gf_inline_is_hardcoded_proto(lib_url, scene->root_od->term->user->config)) return NULL; i=0; while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i)) ) { if (pl->url == lib_url) return NULL; if (pl->url->vals[0].OD_ID && (pl->url->vals[0].OD_ID == lib_url->vals[0].OD_ID)) return NULL; if (pl->url->vals[0].url && lib_url->vals[0].url && !stricmp(pl->url->vals[0].url, lib_url->vals[0].url) ) return NULL; } pl = (GF_ProtoLink*)gf_malloc(sizeof(GF_ProtoLink)); pl->url = lib_url; gf_list_add(scene->extern_protos, pl); pl->mo = gf_scene_get_media_object(scene, lib_url, GF_MEDIA_OBJECT_SCENE, 0); /*this may already be destroyed*/ if (pl->mo) gf_mo_play(pl->mo, 0, -1, 0); /*and return NULL*/ return NULL; }
void gf_inline_on_modified(GF_Node *node) { u32 ODID; GF_MediaObject *mo; M_Inline *pInline = (M_Inline *) node; GF_Scene *scene = (GF_Scene *)gf_node_get_private(node); ODID = gf_mo_get_od_id(&pInline->url); if (scene) { mo = (scene->root_od) ? scene->root_od->mo : NULL; /*disconnect current inline if we're the last one using it (same as regular OD session leave/join)*/ if (mo) { Bool changed = 1; if (ODID != GF_MEDIA_EXTERNAL_ID) { if (ODID && (ODID==scene->root_od->OD->objectDescriptorID)) changed = 0; } else { if (gf_mo_is_same_url(mo, &pInline->url, NULL, 0) ) changed = 0; } if (mo->num_open) { if (!changed) return; gf_scene_notify_event(scene, GF_EVENT_UNLOAD, node, NULL, GF_OK); gf_node_dirty_parents(node); gf_list_del_item(mo->nodes, node); /*reset the scene pointer as it may get destroyed*/ switch (gf_node_get_tag(node)) { case TAG_MPEG4_Inline: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Inline: #endif gf_node_set_private(node, NULL); break; } mo->num_open --; if (!mo->num_open) { if (ODID == GF_MEDIA_EXTERNAL_ID) { GF_Scene *parent = scene->root_od->parentscene; /*!!! THIS WILL DESTROY THE INLINE SCENE OBJECT !!!*/ gf_odm_disconnect(scene->root_od, 1); /*and force removal of the media object*/ if (parent) { if (gf_list_del_item(parent->scene_objects, mo)>=0) { gf_sg_vrml_mf_reset(&mo->URLs, GF_SG_VRML_MFURL); gf_list_del(mo->nodes); gf_free(mo); } } } else { gf_term_lock_media_queue(scene->root_od->term, 1); /*external media are completely unloaded*/ if (scene->root_od->OD->objectDescriptorID==GF_MEDIA_EXTERNAL_ID) { scene->root_od->action_type = GF_ODM_ACTION_DELETE; } else { scene->root_od->action_type = GF_ODM_ACTION_STOP; } if (gf_list_find(scene->root_od->term->media_queue, scene->root_od)<0) gf_list_add(scene->root_od->term->media_queue, scene->root_od); gf_term_lock_media_queue(scene->root_od->term, 0); } } } } } else { gf_node_dirty_parents(node); } if (ODID) gf_inline_set_scene(pInline); }
/*refresh modules - note we don't check for deleted modules but since we've open them the OS should forbid delete*/ u32 gf_modules_refresh(GF_ModuleManager *pm) { if (!pm) return 0; #ifdef WIN32 gf_enum_directory(pm->dir, 0, enum_modules, pm, ".dll"); #elif defined(__APPLE__) #if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_sdl_out.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_soft_raster.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_dummy_in.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_ctx_load.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_svg_in.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_mp3_in.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_aac_in.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_img_in.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_bifs_dec.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_hyb_in.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_gpac_js.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_isom_in.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_laser_dec.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_odf_dec.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_rtp_in.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_mpegts_in.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_ft_font.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_widgetman.dylib"); gf_list_add(pm->plug_list, inst); } { ModuleInstance *inst; GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup("gm_mpd_in.dylib"); gf_list_add(pm->plug_list, inst); } #else gf_enum_directory(pm->dir, 0, enum_modules, pm, ".dylib"); #endif #else GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Refreshing list of modules in directory %s...\n", pm->dir)); gf_enum_directory(pm->dir, 0, enum_modules, pm, ".so"); #endif return gf_list_count(pm->plug_list); }
static void gf_inline_traverse(GF_Node *n, void *rs, Bool is_destroy) { MFURL *current_url; GF_Scene *scene = (GF_Scene *)gf_node_get_private(n); if (is_destroy) { GF_MediaObject *mo; if (!scene) return; mo = scene->root_od ? scene->root_od->mo : NULL; gf_scene_notify_event(scene, GF_EVENT_UNLOAD, n, NULL, GF_OK); if (!mo) return; gf_list_del_item(mo->nodes, n); /*disconnect current inline if we're the last one using it (same as regular OD session leave/join)*/ if (mo->num_open) { mo->num_open --; if (!mo->num_open) { gf_term_lock_media_queue(scene->root_od->term, 1); /*this is unspecified in the spec: whenever an inline not using the OD framework is destroyed, destroy the associated resource*/ if (mo->OD_ID == GF_MEDIA_EXTERNAL_ID) { /*get parent scene and remove MediaObject in case the ressource gets re-requested later on*/ GF_Scene *parent_scene = (GF_Scene *)gf_sg_get_private(gf_node_get_graph((GF_Node *) n) ); if (gf_list_del_item(parent_scene->scene_objects, mo)>=0) { gf_sg_vrml_mf_reset(&mo->URLs, GF_SG_VRML_MFURL); gf_list_del(mo->nodes); if (mo->odm) mo->odm->mo = NULL; gf_free(mo); } scene->root_od->action_type = GF_ODM_ACTION_DELETE; gf_list_add(scene->root_od->term->media_queue, scene->root_od); } else { scene->root_od->action_type = GF_ODM_ACTION_SCENE_DISCONNECT; gf_list_add(scene->root_od->term->media_queue, scene->root_od); } gf_term_lock_media_queue(scene->root_od->term, 0); } } return; } //if no private scene is associated get the node parent graph, retrieve the IS and find the OD if (!scene) { M_Inline *inl = (M_Inline *)n; gf_inline_set_scene(inl); scene = (GF_Scene *)gf_node_get_private(n); if (!scene) { /*just like protos, we must invalidate parent graph until attached*/ if (inl->url.count) { if (!inl->url.vals[0].OD_ID && (!inl->url.vals[0].url || !strlen(inl->url.vals[0].url) ) ) { gf_sg_vrml_mf_reset(&inl->url, GF_SG_VRML_MFURL); } else { gf_node_dirty_set(n, 0, 1); } } return; } } gf_inline_check_restart(scene); /*if we need to restart, shutdown graph and do it*/ if (scene->needs_restart) { /*special case: scene change*/ if (scene->needs_restart==2) { scene->needs_restart = 0; gf_inline_on_modified(n); return; } scene->needs_restart = 0; gf_term_lock_media_queue(scene->root_od->term, 1); scene->root_od->action_type = GF_ODM_ACTION_SCENE_INLINE_RESTART; gf_list_add(scene->root_od->term->media_queue, scene->root_od); gf_term_lock_media_queue(scene->root_od->term, 0); gf_node_dirty_set(n, 0, 1); return; } /*if not attached return (attaching the graph cannot be done in render since render is not called while unattached :) */ if (!scene->graph_attached) { /*just like protos, we must invalidate parent graph until attached*/ gf_node_dirty_set(n, 0, 1); return; } /*clear dirty flags for any sub-inlines, bitmaps or protos*/ gf_node_dirty_clear(n, 0); current_url = scene->current_url; scene->current_url = & ((M_Inline*)n)->url; gf_sc_traverse_subscene(scene->root_od->term->compositor, n, scene->graph, rs); scene->current_url = current_url; }
Bool enum_modules(void *cbck, char *item_name, char *item_path) { ModuleInstance *inst; #if CHECK_MODULE QueryInterface query_func; LoadInterface load_func; ShutdownInterface del_func; #ifdef WIN32 HMODULE ModuleLib; #else void *ModuleLib; s32 _flags; #endif #endif GF_ModuleManager *pm = cbck; if (strstr(item_name, "nposmozilla")) return 0; if (strncmp(item_name, "gm_", 3) && strncmp(item_name, "libgm_", 6)) return 0; if (gf_module_is_loaded(pm, item_name) ) return 0; #if CHECK_MODULE #ifdef WIN32 ModuleLib = LoadLibrary(item_path); if (!ModuleLib) { GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load module file %s\n", item_name)); return 0; } #ifdef _WIN32_WCE query_func = (QueryInterface) GetProcAddress(ModuleLib, _T("QueryInterface")); load_func = (LoadInterface) GetProcAddress(ModuleLib, _T("LoadInterface")); del_func = (ShutdownInterface) GetProcAddress(ModuleLib, _T("ShutdownInterface")); #else query_func = (QueryInterface) GetProcAddress(ModuleLib, "QueryInterface"); load_func = (LoadInterface) GetProcAddress(ModuleLib, "LoadInterface"); del_func = (ShutdownInterface) GetProcAddress(ModuleLib, "ShutdownInterface"); #endif FreeLibrary(ModuleLib); #else #ifdef RTLD_GLOBAL _flags =RTLD_LAZY | RTLD_GLOBAL; #else _flags =RTLD_LAZY; #endif ModuleLib = dlopen(item_name, _flags); if (!ModuleLib) { GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load module file %s, error is %s\n", item_name, dlerror())); goto next; } query_func = (QueryInterface) dlsym(ModuleLib, "QueryInterface"); load_func = (LoadInterface) dlsym(ModuleLib, "LoadInterface"); del_func = (ShutdownInterface) dlsym(ModuleLib, "ShutdownInterface"); dlclose(ModuleLib); #endif if (!load_func || !query_func || !del_func){ GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[Core] Could not find some signatures in module %s: QueryInterface=%p, LoadInterface=%p, ShutdownInterface=%p\n", item_name, load_func, query_func, del_func)); return 0; } #endif GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; inst->name = gf_strdup(item_name); GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[Core] Added module %s.\n", inst->name)); gf_list_add(pm->plug_list, inst); return 0; }
void isor_declare_objects(ISOMReader *read) { GF_ObjectDescriptor *od; GF_ESD *esd; const char *tag; u32 i, count, ocr_es_id, tlen, base_track, j, track_id; Bool highest_stream; ocr_es_id = 0; /*TODO check for alternate tracks*/ count = gf_isom_get_track_count(read->mov); for (i=0; i<count; i++) { if (!gf_isom_is_track_enabled(read->mov, i+1)) continue; switch (gf_isom_get_media_type(read->mov, i+1)) { case GF_ISOM_MEDIA_AUDIO: case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_TEXT: case GF_ISOM_MEDIA_SUBT: case GF_ISOM_MEDIA_SCENE: case GF_ISOM_MEDIA_SUBPIC: break; default: continue; } //some subtypes are not declared as readable objects switch (gf_isom_get_media_subtype(read->mov, i+1, 1)) { case GF_ISOM_SUBTYPE_HVT1: continue; default: break; } /*we declare only the highest video track (i.e the track we play)*/ highest_stream = GF_TRUE; track_id = gf_isom_get_track_id(read->mov, i+1); if (read->play_only_track_id && (read->play_only_track_id != track_id)) continue; for (j = 0; j < count; j++) { if (gf_isom_has_track_reference(read->mov, j+1, GF_ISOM_REF_SCAL, track_id) > 0) { highest_stream = GF_FALSE; break; } } if ((gf_isom_get_media_type(read->mov, i+1) == GF_ISOM_MEDIA_VISUAL) && !highest_stream) continue; esd = gf_media_map_esd(read->mov, i+1); if (esd) { gf_isom_get_reference(read->mov, i+1, GF_ISOM_REF_BASE, 1, &base_track); esd->has_ref_base = base_track ? GF_TRUE : GF_FALSE; if (!esd->langDesc) { esd->langDesc = (GF_Language *) gf_odf_desc_new(GF_ODF_LANG_TAG); gf_isom_get_media_language(read->mov, i+1, &esd->langDesc->full_lang_code); } od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); od->service_ifce = read->input; od->objectDescriptorID = 0; if (!ocr_es_id) ocr_es_id = esd->ESID; esd->OCRESID = ocr_es_id; gf_list_add(od->ESDescriptors, esd); if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_FALSE, GF_TRUE, GF_OK, (GF_Descriptor*)od, NULL); } else { gf_service_declare_media(read->service, (GF_Descriptor*)od, GF_TRUE); } } } /*if cover art, extract it in cache*/ if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_COVER_ART, &tag, &tlen)==GF_OK) { const char *cdir = gf_modules_get_option((GF_BaseInterface *)gf_service_get_interface(read->service), "General", "CacheDirectory"); if (cdir) { char szName[GF_MAX_PATH]; const char *sep; FILE *t; sep = strrchr(gf_isom_get_filename(read->mov), '\\'); if (!sep) sep = strrchr(gf_isom_get_filename(read->mov), '/'); if (!sep) sep = gf_isom_get_filename(read->mov); if ((cdir[strlen(cdir)-1] != '\\') && (cdir[strlen(cdir)-1] != '/')) { sprintf(szName, "%s/%s_cover.%s", cdir, sep, (tlen & 0x80000000) ? "png" : "jpg"); } else { sprintf(szName, "%s%s_cover.%s", cdir, sep, (tlen & 0x80000000) ? "png" : "jpg"); } t = gf_fopen(szName, "wb"); if (t) { Bool isom_contains_video = GF_FALSE; /*write cover data*/ assert(!(tlen & 0x80000000)); gf_fwrite(tag, tlen & 0x7FFFFFFF, 1, t); gf_fclose(t); /*don't display cover art when video is present*/ for (i=0; i<gf_isom_get_track_count(read->mov); i++) { if (!gf_isom_is_track_enabled(read->mov, i+1)) continue; if (gf_isom_get_media_type(read->mov, i+1) == GF_ISOM_MEDIA_VISUAL) { isom_contains_video = GF_TRUE; break; } } if (!isom_contains_video) { od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); od->service_ifce = read->input; od->objectDescriptorID = GF_MEDIA_EXTERNAL_ID; od->URLString = gf_strdup(szName); if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_FALSE, GF_TRUE, GF_OK, (GF_Descriptor*)od, NULL); } else { gf_service_declare_media(read->service, (GF_Descriptor*)od, GF_TRUE); } } } } } if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_FALSE, GF_TRUE, GF_OK, NULL, NULL); } else { gf_service_declare_media(read->service, NULL, GF_FALSE); } }
GF_EXPORT GF_BaseInterface *gf_modules_load_interface(GF_ModuleManager *pm, u32 whichplug, u32 InterfaceFamily) { const char *opt; char szKey[32]; ModuleInstance *inst; GF_BaseInterface *ifce; if (!pm) { GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] gf_modules_load_interface() : No Module Manager set\n")); return NULL; } gf_mx_p(pm->mutex); inst = (ModuleInstance *) gf_list_get(pm->plug_list, whichplug); if (!inst) { GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] gf_modules_load_interface() : no module %d exist.\n", whichplug)); gf_mx_v(pm->mutex); return NULL; } GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface...%s\n", inst->name)); /*look in cache*/ if (!pm->cfg) { GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] No pm->cfg has been set !!!\n")); gf_mx_v(pm->mutex); return NULL; } opt = gf_cfg_get_key(pm->cfg, "PluginsCache", inst->name); if (opt) { const char * ifce_str = gf_4cc_to_str(InterfaceFamily); snprintf(szKey, 32, "%s:yes", ifce_str ? ifce_str : "(null)"); if (!strstr(opt, szKey)) { gf_mx_v(pm->mutex); return NULL; } } if (!gf_modules_load_library(inst)) { GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load library %s\n", inst->name)); gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "Invalid Plugin"); gf_mx_v(pm->mutex); return NULL; } if (!inst->query_func) { GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Library %s missing GPAC export symbols\n", inst->name)); gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "Invalid Plugin"); goto err_exit; } /*build cache*/ if (!opt) { u32 i; Bool found = GF_FALSE; char *key; const u32 *si = inst->query_func(); if (!si) { GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[Core] GPAC module %s has no supported interfaces - disabling\n", inst->name)); gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "Invalid Plugin"); goto err_exit; } i=0; while (si[i]) i++; key = (char*)gf_malloc(sizeof(char) * 10 * i); key[0] = 0; i=0; while (si[i]) { snprintf(szKey, 32, "%s:yes ", gf_4cc_to_str(si[i])); strcat(key, szKey); if (InterfaceFamily==si[i]) found = GF_TRUE; i++; } gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, key); gf_free(key); if (!found) goto err_exit; } if (!inst->query_func || !inst->query_func(InterfaceFamily) ) goto err_exit; ifce = (GF_BaseInterface *) inst->load_func(InterfaceFamily); /*sanity check*/ if (!ifce) goto err_exit; if (!ifce->module_name || (ifce->InterfaceType != InterfaceFamily)) { inst->destroy_func(ifce); goto err_exit; } gf_list_add(inst->interfaces, ifce); /*keep track of parent*/ ifce->HPLUG = inst; GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s DONE.\n", inst->name)); gf_mx_v(pm->mutex); return ifce; err_exit: GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s exit label, freing library...\n", inst->name)); gf_modules_unload_library(inst); GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s EXIT.\n", inst->name)); gf_mx_v(pm->mutex); return NULL; }
void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value) { char LineBuffer[400], buf[1000], param_name[100], param_val[1000]; s32 LinePos, Pos, nPos, s_val; GF_RTPInfo *info; GF_RTSPTransport *trans; GF_X_Attribute *x_Att; if (!stricmp(Header, "Accept")) rsp->Accept = gf_strdup(Value); else if (!stricmp(Header, "Accept-Encoding")) rsp->Accept_Encoding = gf_strdup(Value); else if (!stricmp(Header, "Accept-Language")) rsp->Accept_Language = gf_strdup(Value); else if (!stricmp(Header, "Allow")) rsp->Allow = gf_strdup(Value); else if (!stricmp(Header, "Authorization")) rsp->Authorization = gf_strdup(Value); else if (!stricmp(Header, "Bandwidth")) sscanf(Value, "%u", &rsp->Bandwidth); else if (!stricmp(Header, "Blocksize")) sscanf(Value, "%u", &rsp->Blocksize); else if (!stricmp(Header, "Cache-Control")) rsp->Cache_Control = gf_strdup(Value); else if (!stricmp(Header, "com.ses.streamID")) sscanf(Value, "%u", &rsp->StreamID); else if (!stricmp(Header, "Conference")) rsp->Conference = gf_strdup(Value); else if (!stricmp(Header, "Connection")) rsp->Connection = gf_strdup(Value); else if (!stricmp(Header, "Content-Base")) rsp->Content_Base = gf_strdup(Value); else if (!stricmp(Header, "Content-Encoding")) rsp->Content_Encoding = gf_strdup(Value); else if (!stricmp(Header, "Content-Length")) sscanf(Value, "%u", &rsp->Content_Length); else if (!stricmp(Header, "Content-Language")) rsp->Content_Language = gf_strdup(Value); else if (!stricmp(Header, "Content-Location")) rsp->Content_Location = gf_strdup(Value); else if (!stricmp(Header, "Content-Type")) rsp->Content_Type = gf_strdup(Value); else if (!stricmp(Header, "CSeq")) sscanf(Value, "%u", &rsp->CSeq); else if (!stricmp(Header, "Date")) rsp->Date = gf_strdup(Value); else if (!stricmp(Header, "Expires")) rsp->Expires = gf_strdup(Value); else if (!stricmp(Header, "From")) rsp->From = gf_strdup(Value); else if (!stricmp(Header, "Host")) rsp->Host = gf_strdup(Value); else if (!stricmp(Header, "If-Match")) rsp->If_Match = gf_strdup(Value); else if (!stricmp(Header, "If-Modified-Since")) rsp->If_Modified_Since = gf_strdup(Value); else if (!stricmp(Header, "Last-Modified")) rsp->Last_Modified = gf_strdup(Value); else if (!stricmp(Header, "Location")) rsp->Location = gf_strdup(Value); else if (!stricmp(Header, "Proxy-Authenticate")) rsp->Proxy_Authenticate = gf_strdup(Value); else if (!stricmp(Header, "Proxy-Require")) rsp->Proxy_Require = gf_strdup(Value); else if (!stricmp(Header, "Public")) rsp->Public = gf_strdup(Value); else if (!stricmp(Header, "Referer")) rsp->Referer = gf_strdup(Value); else if (!stricmp(Header, "Require")) rsp->Require = gf_strdup(Value); else if (!stricmp(Header, "Retry-After")) rsp->Retry_After = gf_strdup(Value); else if (!stricmp(Header, "Scale")) sscanf(Value, "%lf", &rsp->Scale); else if (!stricmp(Header, "Server")) rsp->Server = gf_strdup(Value); else if (!stricmp(Header, "Speed")) sscanf(Value, "%lf", &rsp->Speed); else if (!stricmp(Header, "Timestamp")) rsp->Timestamp = gf_strdup(Value); else if (!stricmp(Header, "Unsupported")) rsp->Unsupported = gf_strdup(Value); else if (!stricmp(Header, "User-Agent")) rsp->User_Agent = gf_strdup(Value); else if (!stricmp(Header, "Vary")) rsp->Vary = gf_strdup(Value); else if (!stricmp(Header, "Via")) rsp->Vary = gf_strdup(Value); else if (!stricmp(Header, "WWW_Authenticate")) rsp->Vary = gf_strdup(Value); else if (!stricmp(Header, "Transport")) { LinePos = 0; while (1) { LinePos = gf_token_get(Value, LinePos, "\r\n", LineBuffer, 400); if (LinePos <= 0) return; trans = gf_rtsp_transport_parse(Value); if (trans) gf_list_add(rsp->Transports, trans); } } //Session else if (!stricmp(Header, "Session")) { LinePos = gf_token_get(Value, 0, ";\r\n", LineBuffer, 400); rsp->Session = gf_strdup(LineBuffer); //get timeout if any if (Value[LinePos] == ';') { LinePos += 1; /*LinePos = */gf_token_get(Value, LinePos, ";\r\n", LineBuffer, 400); rsp->SessionTimeOut = 60; //default sscanf(LineBuffer, "timeout=%u", &rsp->SessionTimeOut); } } //Range else if (!stricmp(Header, "Range")) rsp->Range = gf_rtsp_range_parse(Value); //RTP-Info else if (!stricmp(Header, "RTP-Info")) { LinePos = 0; while (1) { LinePos = gf_token_get(Value, LinePos, ",\r\n", LineBuffer, 400); if (LinePos <= 0) return; GF_SAFEALLOC(info, GF_RTPInfo); if (!info) return; Pos = 0; while (1) { Pos = gf_token_get(LineBuffer, Pos, " ;", buf, 1000); if (Pos <= 0) break; if (strstr(buf, "=")) { nPos = gf_token_get(buf, 0, "=", param_name, 100); nPos += 1; /*nPos = */gf_token_get(buf, nPos, "", param_val, 1000); } else { strcpy(param_name, buf); } if (!stricmp(param_name, "url")) info->url = gf_strdup(param_val); else if (!stricmp(param_name, "seq")) sscanf(param_val, "%u", &info->seq); else if (!stricmp(param_name, "rtptime")) { sscanf(param_val, "%i", &s_val); info->rtp_time = (s_val>0) ? s_val : 0; } else if (!stricmp(param_name, "ssrc")) { sscanf(param_val, "%i", &s_val); info->ssrc = (s_val>0) ? s_val : 0; } } gf_list_add(rsp->RTP_Infos, info); } } //check for extended attributes else if (!strnicmp(Header, "x-", 2)) { x_Att = (GF_X_Attribute*)gf_malloc(sizeof(GF_X_Attribute)); x_Att->Name = gf_strdup(Header+2); x_Att->Value = NULL; if (Value && strlen(Value)) x_Att->Value = gf_strdup(Value); gf_list_add(rsp->Xtensions, x_Att); } //unknown field - skip it }
GF_Err gf_webvtt_merge_cues(GF_WebVTTParser *parser, u64 start, GF_List *cues) { GF_WebVTTSample *wsample; GF_WebVTTSample *prev_wsample; Bool has_continuation_cue = GF_FALSE; assert(gf_list_count(parser->samples) <= 1); wsample = gf_webvtt_sample_new(); wsample->start = start; prev_wsample = (GF_WebVTTSample *)gf_list_last(parser->samples); while (gf_list_count(cues)) { GF_WebVTTCue *cue = (GF_WebVTTCue *)gf_list_get(cues, 0); gf_list_rem(cues, 0); /* add the cue to the current sample */ gf_list_add(wsample->cues, cue); /* update with the previous sample */ if (prev_wsample) { Bool found = GF_FALSE; while (!found && gf_list_count(prev_wsample->cues)) { GF_WebVTTCue *old_cue = (GF_WebVTTCue *)gf_list_get(prev_wsample->cues, 0); gf_list_rem(prev_wsample->cues, 0); if ( ((!cue->id && !old_cue->id) || (old_cue->id && cue->id && !strcmp(old_cue->id, cue->id))) && ((!cue->settings && !old_cue->settings) || (old_cue->settings && cue->settings && !strcmp(old_cue->settings, cue->settings))) && ((!cue->text && !old_cue->text) || (old_cue->text && cue->text && !strcmp(old_cue->text, cue->text))) ) { /* if it is the same cue, update its start with the initial start */ cue->start = old_cue->start; has_continuation_cue = GF_TRUE; found = GF_TRUE; if (old_cue->pre_text) { cue->pre_text = old_cue->pre_text; old_cue->pre_text = NULL; } if (old_cue->post_text) { cue->post_text = old_cue->post_text; old_cue->post_text = NULL; } } else { /* finalize the end cue time */ if (gf_webvtt_timestamp_is_zero(&old_cue->end)) { gf_webvtt_timestamp_set(&old_cue->end, wsample->start); } /* transfer the cue */ if (!has_continuation_cue) { /* the cue can be safely serialized while keeping the order */ parser->on_cue_read(parser->user, old_cue); } else { /* keep the cue in the current sample to respect cue start ordering */ gf_list_add(wsample->cues, old_cue); } } /* delete the old cue */ gf_webvtt_cue_del(old_cue); } } } /* No cue in the current sample */ if (prev_wsample) { while (gf_list_count(prev_wsample->cues)) { GF_WebVTTCue *cue = (GF_WebVTTCue *)gf_list_get(prev_wsample->cues, 0); gf_list_rem(prev_wsample->cues, 0); /* finalize the end cue time */ if (gf_webvtt_timestamp_is_zero(&cue->end)) { gf_webvtt_timestamp_set(&cue->end, wsample->start); } /* transfer the cue */ if (!has_continuation_cue) { /* the cue can be safely serialized while keeping the order */ parser->on_cue_read(parser->user, cue); } else { /* keep the cue in the current sample to respect cue start ordering */ gf_list_add(wsample->cues, cue); } gf_webvtt_cue_del(cue); } gf_webvtt_sample_del(prev_wsample); gf_list_rem_last(parser->samples); prev_wsample = NULL; } else { /* nothing to do */ } if (gf_list_count(wsample->cues)) { gf_list_add(parser->samples, wsample); } else { gf_webvtt_sample_del(wsample); } return GF_OK; }
GF_Node *CloneNodeForEditing(GF_SceneGraph *inScene, GF_Node *orig) //, GF_Node *cloned_parent) { u32 i, j, count; GF_Node *node, *child, *tmp; GF_List *list, *list2; GF_FieldInfo field_orig, field; /*this is not a mistake*/ if (!orig) return NULL; /*check for DEF/USE if (orig->sgprivate->NodeID) { node = gf_sg_find_node(inScene, orig->sgprivate->NodeID); //node already created, USE if (node) { gf_node_register(node, cloned_parent); return node; } } */ /*create a node*/ /* if (orig->sgprivate->tag == TAG_MPEG4_ProtoNode) { proto_node = ((GF_ProtoInstance *)orig)->proto_interface; //create the instance but don't load the code -c we MUST wait for ISed routes to be cloned before node = gf_sg_proto_create_node(inScene, proto_node, (GF_ProtoInstance *) orig); } else { */ node = gf_node_new(inScene, gf_node_get_tag(orig)); // } count = gf_node_get_field_count(orig); /*copy each field*/ for (i=0; i<count; i++) { gf_node_get_field(orig, i, &field_orig); /*get target ptr*/ gf_node_get_field(node, i, &field); assert(field.eventType==field_orig.eventType); assert(field.fieldType==field_orig.fieldType); /*duplicate it*/ switch (field.fieldType) { case GF_SG_VRML_SFNODE: child = CloneNodeForEditing(inScene, (GF_Node *) (* ((GF_Node **) field_orig.far_ptr)));//, node); *((GF_Node **) field.far_ptr) = child; break; case GF_SG_VRML_MFNODE: list = *( (GF_List **) field_orig.far_ptr); list2 = *( (GF_List **) field.far_ptr); for (j=0; j<gf_list_count(list); j++) { tmp = (GF_Node *)gf_list_get(list, j); child = CloneNodeForEditing(inScene, tmp);//, node); gf_list_add(list2, child); } break; default: gf_sg_vrml_field_copy(field.far_ptr, field_orig.far_ptr, field.fieldType); break; } } /*register node if (orig->sgprivate->NodeID) { Node_SetID(node, orig->sgprivate->NodeID); gf_node_register(node, cloned_parent); }*/ /*init node before creating ISed routes so the eventIn handler are in place*/ if (gf_node_get_tag(node) != TAG_ProtoNode) gf_node_init(node); return node; }
static GF_Err gf_webvtt_add_cue_to_samples(GF_WebVTTParser *parser, GF_List *samples, GF_WebVTTCue *cue) { s32 i; u64 cue_start; u64 cue_end; u64 sample_end; sample_end = 0; cue_start = gf_webvtt_timestamp_get(&cue->start); cue_end = gf_webvtt_timestamp_get(&cue->end); /* samples in the samples list are contiguous: sample(n)->start == sample(n-1)->end */ for (i = 0; i < (s32)gf_list_count(samples); i++) { GF_WebVTTSample *sample; sample = (GF_WebVTTSample *)gf_list_get(samples, i); /* save the sample end in case there are no more samples to test */ sample_end = sample->end; if (cue_start < sample->start) { /* cues must be ordered according to their start time, so drop the cue */ /* TODO delete the cue */ return GF_BAD_PARAM; } else if (cue_start == sample->start && cue_end == sample->end) { /* if the timing of the new cue matches the sample, no need to split, add the cue to the sample */ gf_list_add(sample->cues, cue); /* the cue does not need to processed further */ return GF_OK; } else if (cue_start >= sample->end) { /* flush the current sample */ gf_list_del_item(samples, sample); parser->on_sample_parsed(parser->user, sample); sample = NULL; i--; /* process the cue with next sample (if any) or create a new sample */ continue; } else if (cue_start >= sample->start) { u32 j; if (cue_start > sample->start) { /* create a new sample, insert it after the current one */ GF_WebVTTSample *new_sample = gf_webvtt_sample_new(); new_sample->start = cue_start; new_sample->end = sample->end; gf_list_insert(samples, new_sample, i+1); /* split the cues from the old sample into the new one */ for (j = 0; j < gf_list_count(sample->cues); j++) { GF_WebVTTCue *old_cue = (GF_WebVTTCue *)gf_list_get(sample->cues, j); GF_WebVTTCue *new_cue = gf_webvtt_cue_split_at(old_cue, &cue->start); gf_list_add(new_sample->cues, new_cue); } /* adjust the end of the old sample and flush it */ sample->end = cue_start; gf_list_del_item(samples, sample); parser->on_sample_parsed(parser->user, sample); sample = NULL; i--; /* process the cue again with this new sample */ continue; } if (cue_end > sample->end) { /* the cue is longer than the sample, we split the cue, add one part to the current sample and reevaluate with the last part of the cue */ GF_WebVTTCue *old_cue = (GF_WebVTTCue *)gf_list_get(sample->cues, 0); GF_WebVTTCue *new_cue = gf_webvtt_cue_split_at(cue, &old_cue->end); gf_list_add(sample->cues, cue); cue = new_cue; cue_start = sample->end; /* cue_end unchanged */ /* process the remaining part of the cue (i.e. the new cue) with the other samples */ continue; } else { /* cue_end < sample->end */ GF_WebVTTSample *new_sample = gf_webvtt_sample_new(); new_sample->start = cue_end; new_sample->end = sample->end; gf_list_insert(samples, new_sample, i+1); for (j = 0; j < gf_list_count(sample->cues); j++) { GF_WebVTTCue *old_cue = (GF_WebVTTCue *)gf_list_get(sample->cues, j); GF_WebVTTCue *new_cue = gf_webvtt_cue_split_at(old_cue, &cue->end); gf_list_add(new_sample->cues, new_cue); } gf_list_add(sample->cues, cue); sample->end = new_sample->start; /* done with this cue */ return GF_OK; } } } /* (a part of) the cue remains (was not overlapping) */ if (cue_start > sample_end) { /* if the new cue start is greater than the last sample end, create an empty sample to fill the gap, flush it */ GF_WebVTTSample *esample = gf_webvtt_sample_new(); esample->start = sample_end; esample->end = cue_start; parser->on_sample_parsed(parser->user, esample); } /* if the cue has not been added to a sample, create a new sample for it */ { GF_WebVTTSample *sample; sample = gf_webvtt_sample_new(); gf_list_add(samples, sample); sample->start = cue_start; sample->end = cue_end; gf_list_add(sample->cues, cue); } return GF_OK; }
// Update the dependancies when an OD AU is inserted in the file GF_Err Media_ParseODFrame(GF_MediaBox *mdia, GF_ISOSample *sample, GF_ISOSample **od_samp) { GF_TrackReferenceBox *tref; GF_TrackReferenceTypeBox *mpod; GF_Err e; GF_ODCom *com; GF_ODCodec *ODencode; GF_ODCodec *ODdecode; u32 i, j; //the commands we proceed GF_ESDUpdate *esdU, *esdU2; GF_ESDRemove *esdR, *esdR2; GF_ODUpdate *odU, *odU2; //the desc they contain GF_ObjectDescriptor *od; GF_IsomObjectDescriptor *isom_od; GF_ESD *esd; GF_ES_ID_Ref *ref; GF_Descriptor *desc; *od_samp = NULL; if (!mdia || !sample || !sample->data || !sample->dataLength) return GF_BAD_PARAM; //First find the references, and create them if none tref = mdia->mediaTrack->References; if (!tref) { tref = (GF_TrackReferenceBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TREF); e = trak_AddBox((GF_Box*)mdia->mediaTrack, (GF_Box *) tref); if (e) return e; } //then find the OD reference, and create it if none e = Track_FindRef(mdia->mediaTrack, GF_ISOM_BOX_TYPE_MPOD, &mpod); if (e) return e; if (!mpod) { mpod = (GF_TrackReferenceTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_REFT); mpod->reference_type = GF_ISOM_BOX_TYPE_MPOD; e = tref_AddBox((GF_Box*)tref, (GF_Box *)mpod); if (e) return e; } //OK, create our codecs ODencode = gf_odf_codec_new(); if (!ODencode) return GF_OUT_OF_MEM; ODdecode = gf_odf_codec_new(); if (!ODdecode) return GF_OUT_OF_MEM; e = gf_odf_codec_set_au(ODdecode, sample->data, sample->dataLength); if (e) goto err_exit; e = gf_odf_codec_decode(ODdecode); if (e) goto err_exit; while (1) { com = gf_odf_codec_get_com(ODdecode); if (!com) break; //check our commands switch (com->tag) { //Rewrite OD Update case GF_ODF_OD_UPDATE_TAG: //duplicate our command odU = (GF_ODUpdate *) com; odU2 = (GF_ODUpdate *) gf_odf_com_new(GF_ODF_OD_UPDATE_TAG); i=0; while ((desc = (GF_Descriptor*)gf_list_enum(odU->objectDescriptors, &i))) { //both OD and IODs are accepted switch (desc->tag) { case GF_ODF_OD_TAG: case GF_ODF_IOD_TAG: break; default: e = GF_ODF_INVALID_DESCRIPTOR; goto err_exit; } //get the esd e = gf_odf_desc_copy(desc, (GF_Descriptor **)&od); if (e) goto err_exit; if (desc->tag == GF_ODF_OD_TAG) { isom_od = (GF_IsomObjectDescriptor *) gf_malloc(sizeof(GF_IsomObjectDescriptor)); isom_od->tag = GF_ODF_ISOM_OD_TAG; } else { isom_od = (GF_IsomObjectDescriptor *) gf_malloc(sizeof(GF_IsomInitialObjectDescriptor)); isom_od->tag = GF_ODF_ISOM_IOD_TAG; //copy PL ((GF_IsomInitialObjectDescriptor *)isom_od)->inlineProfileFlag = ((GF_InitialObjectDescriptor *)od)->inlineProfileFlag; ((GF_IsomInitialObjectDescriptor *)isom_od)->graphics_profileAndLevel = ((GF_InitialObjectDescriptor *)od)->graphics_profileAndLevel; ((GF_IsomInitialObjectDescriptor *)isom_od)->audio_profileAndLevel = ((GF_InitialObjectDescriptor *)od)->audio_profileAndLevel; ((GF_IsomInitialObjectDescriptor *)isom_od)->OD_profileAndLevel = ((GF_InitialObjectDescriptor *)od)->OD_profileAndLevel; ((GF_IsomInitialObjectDescriptor *)isom_od)->scene_profileAndLevel = ((GF_InitialObjectDescriptor *)od)->scene_profileAndLevel; ((GF_IsomInitialObjectDescriptor *)isom_od)->visual_profileAndLevel = ((GF_InitialObjectDescriptor *)od)->visual_profileAndLevel; ((GF_IsomInitialObjectDescriptor *)isom_od)->IPMPToolList = ((GF_InitialObjectDescriptor *)od)->IPMPToolList; ((GF_InitialObjectDescriptor *)od)->IPMPToolList = NULL; } //in OD stream only ref desc are accepted isom_od->ES_ID_RefDescriptors = gf_list_new(); isom_od->ES_ID_IncDescriptors = NULL; //TO DO: check that a given sampleDescription exists isom_od->extensionDescriptors = od->extensionDescriptors; od->extensionDescriptors = NULL; isom_od->IPMP_Descriptors = od->IPMP_Descriptors; od->IPMP_Descriptors = NULL; isom_od->OCIDescriptors = od->OCIDescriptors; od->OCIDescriptors = NULL; isom_od->URLString = od->URLString; od->URLString = NULL; isom_od->objectDescriptorID = od->objectDescriptorID; j=0; while ((esd = (GF_ESD*)gf_list_enum(od->ESDescriptors, &j))) { ref = (GF_ES_ID_Ref *) gf_odf_desc_new(GF_ODF_ESD_REF_TAG); //1 to 1 mapping trackID and ESID. Add this track to MPOD //if track does not exist, this will be remove while reading the OD stream e = reftype_AddRefTrack(mpod, esd->ESID, &ref->trackRef); e = gf_odf_desc_add_desc((GF_Descriptor *)isom_od, (GF_Descriptor *)ref); if (e) goto err_exit; } //delete our desc gf_odf_desc_del((GF_Descriptor *)od); //and add the new one to our command gf_list_add(odU2->objectDescriptors, isom_od); } //delete the command gf_odf_com_del((GF_ODCom **)&odU); //and add the new one to the codec gf_odf_codec_add_com(ODencode, (GF_ODCom *)odU2); break; //Rewrite ESD Update case GF_ODF_ESD_UPDATE_TAG: esdU = (GF_ESDUpdate *) com; esdU2 = (GF_ESDUpdate *) gf_odf_com_new(GF_ODF_ESD_UPDATE_TAG); esdU2->ODID = esdU->ODID; i=0; while ((esd = (GF_ESD*)gf_list_enum(esdU->ESDescriptors, &i))) { ref = (GF_ES_ID_Ref *) gf_odf_desc_new(GF_ODF_ESD_REF_TAG); //1 to 1 mapping trackID and ESID e = reftype_AddRefTrack(mpod, esd->ESID, &ref->trackRef); e = gf_list_add(esdU2->ESDescriptors, ref); if (e) goto err_exit; } gf_odf_com_del((GF_ODCom **)&esdU); gf_odf_codec_add_com(ODencode, (GF_ODCom *)esdU2); break; //Brand new case: the ESRemove has to be rewritten too according to the specs... case GF_ODF_ESD_REMOVE_TAG: esdR = (GF_ESDRemove *) com; esdR2 = (GF_ESDRemove *) gf_odf_com_new(GF_ODF_ESD_REMOVE_TAG); //change the tag for the file format esdR2->tag = GF_ODF_ESD_REMOVE_REF_TAG; esdR2->ODID = esdR->ODID; esdR2->NbESDs = esdR->NbESDs; if (esdR->NbESDs) { //alloc our stuff esdR2->ES_ID = (unsigned short*)gf_malloc(sizeof(u32) * esdR->NbESDs); if (!esdR2->ES_ID) { e = GF_OUT_OF_MEM; goto err_exit; } for (i = 0; i < esdR->NbESDs; i++) { //1 to 1 mapping trackID and ESID e = reftype_AddRefTrack(mpod, esdR->ES_ID[i], &esdR2->ES_ID[i]); if (e) goto err_exit; } } gf_odf_com_del(&com); gf_odf_codec_add_com(ODencode, (GF_ODCom *)esdR2); break; //Add the command as is default: e = gf_odf_codec_add_com(ODencode, com); if (e) goto err_exit; } } //encode our new AU e = gf_odf_codec_encode(ODencode, 1); if (e) goto err_exit; //and set the buffer in the sample *od_samp = gf_isom_sample_new(); (*od_samp)->CTS_Offset = sample->CTS_Offset; (*od_samp)->DTS = sample->DTS; (*od_samp)->IsRAP = sample->IsRAP; e = gf_odf_codec_get_au(ODencode, & (*od_samp)->data, & (*od_samp)->dataLength); if (e) { gf_isom_sample_del(od_samp); *od_samp = NULL; } err_exit: gf_odf_codec_del(ODencode); gf_odf_codec_del(ODdecode); return e; }
GF_EXPORT GF_Err gf_oci_codec_decode(OCICodec *codec, char *au, u32 au_length) { OCIEvent *ev; GF_BitStream *bs; u32 size, hdrS, desc_size, tot_size, tmp_size, val; GF_Descriptor *tmp; GF_Err e; //must be decoder if (!codec || codec->Mode || !au) return GF_BAD_PARAM; bs = gf_bs_new(au, au_length, GF_BITSTREAM_READ); ev = 0; tot_size = 0; while (tot_size < au_length) { //create an event ev = gf_oci_event_new(0); if (!ev) { e = GF_OUT_OF_MEM; goto err_exit; } //FIX IM1 gf_bs_read_int(bs, 8); size = 0; //get its size hdrS = 0; do { val = gf_bs_read_int(bs, 8); hdrS += 1; size <<= 7; size |= val & 0x7F; } while ( val & 0x80 ); //parse event vars ev->EventID = gf_bs_read_int(bs, 15); ev->AbsoluteTimeFlag = gf_bs_read_int(bs, 1); gf_bs_read_data(bs, ev->StartingTime, 4); gf_bs_read_data(bs, ev->duration, 4); desc_size = 0; //parse descriptor list while (desc_size < size - 10) { e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size); //RE-FIX IM1 if (e || !tmp) goto err_exit; if (!OCI_IsOCIDesc(tmp)) { gf_odf_delete_descriptor(tmp); e = GF_ODF_INVALID_DESCRIPTOR; goto err_exit; } gf_list_add(ev->OCIDescriptors, tmp); desc_size += tmp_size + gf_odf_size_field_size(tmp_size); } if (desc_size != size - 10) { e = GF_CORRUPTED_DATA; goto err_exit; } gf_list_add(codec->OCIEvents, ev); //FIX IM1 size += 1; tot_size += size + hdrS; ev = NULL; } if (tot_size != au_length) { e = GF_CORRUPTED_DATA; goto err_exit; } gf_bs_del(bs); return GF_OK; err_exit: gf_bs_del(bs); if (ev) gf_oci_event_del(ev); //delete everything while (gf_list_count(codec->OCIEvents)) { ev = (OCIEvent *)gf_list_get(codec->OCIEvents, 0); gf_list_rem(codec->OCIEvents, 0); gf_oci_event_del(ev); } return e; }
static GF_Err gf_sm_live_setup(GF_SceneEngine *seng) { GF_Err e; GF_StreamContext *sc; GF_InitialObjectDescriptor *iod; GF_ESD *esd; u32 i, j; e = GF_OK; iod = (GF_InitialObjectDescriptor *) seng->ctx->root_od; /*build an IOD*/ if (!iod) { seng->ctx->root_od = (GF_ObjectDescriptor*) gf_odf_desc_new(GF_ODF_IOD_TAG); iod = (GF_InitialObjectDescriptor *) seng->ctx->root_od; i=0; while ((sc = gf_list_enum(seng->ctx->streams, &i))) { if (sc->streamType != GF_STREAM_SCENE) continue; if (!sc->ESID) sc->ESID = 1; esd = gf_odf_desc_esd_new(2); gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo); esd->decoderConfig->decoderSpecificInfo = NULL; esd->ESID = sc->ESID; esd->decoderConfig->streamType = GF_STREAM_SCENE; esd->decoderConfig->objectTypeIndication = sc->objectType; gf_list_add(iod->ESDescriptors, esd); if (!sc->timeScale) sc->timeScale = 1000; esd->slConfig->timestampResolution = sc->timeScale; } } i=0; while ((sc = (GF_StreamContext*)gf_list_enum(seng->ctx->streams, &i))) { j=0; while ((esd = gf_list_enum(seng->ctx->root_od->ESDescriptors, &j))) { if (sc->ESID==esd->ESID) { break; } } if (!esd) continue; if (!esd->slConfig) esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); if (!esd->slConfig->timestampResolution) esd->slConfig->timestampResolution = 1000; if (!sc->timeScale) sc->timeScale = esd->slConfig->timestampResolution; if (sc->streamType == GF_STREAM_SCENE) { switch (sc->objectType) { #ifndef GPAC_DISABLE_BIFS_ENC case GPAC_OTI_SCENE_BIFS: case GPAC_OTI_SCENE_BIFS_V2: e = gf_sm_setup_bifsenc(seng, sc, esd); break; #endif #ifndef GPAC_DISABLE_LASER case GPAC_OTI_SCENE_LASER: e = gf_sm_setup_lsrenc(seng, sc, esd); break; #endif case GPAC_OTI_SCENE_DIMS: /* Nothing to be done here */ break; default: e = GF_NOT_SUPPORTED; break; } if (e) return e; } } return e; }
static GF_Err ft_set_font(GF_FontReader *dr, const char *OrigFontName, u32 styles) { char *fname; char *fontName; const char *opt; FTBuilder *ftpriv = (FTBuilder *)dr->udta; fontName = (char *) OrigFontName; ftpriv->active_face = NULL; if (!fontName || !strlen(fontName) || !stricmp(fontName, "SERIF")) { fontName = ftpriv->font_serif; } else if (!stricmp(fontName, "SANS") || !stricmp(fontName, "sans-serif")) { fontName = ftpriv->font_sans; } else if (!stricmp(fontName, "TYPEWRITER") || !stricmp(fontName, "monospace")) { fontName = ftpriv->font_fixed; } /*first look in loaded fonts*/ ftpriv->active_face = ft_font_in_cache(ftpriv, fontName, styles); if (ftpriv->active_face) return GF_OK; /*check cfg file - gf_free(type is slow at loading fonts so we keep the (font name + styles)=fontfile associations in the cfg file*/ if (!fontName || !strlen(fontName)) return GF_NOT_SUPPORTED; fname = gf_malloc(sizeof(char) * (strlen(fontName) + 50)); { int checkStyles = (styles & GF_FONT_WEIGHT_BOLD) | (styles & GF_FONT_ITALIC); checkFont: strcpy(fname, fontName); if (styles & GF_FONT_WEIGHT_BOLD & checkStyles) strcat(fname, " Bold"); if (styles & GF_FONT_ITALIC & checkStyles) strcat(fname, " Italic"); opt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", fname); if (opt) { FT_Face face; gf_free(fname); if (FT_New_Face(ftpriv->library, opt, 0, & face )) return GF_IO_ERR; if (!face) return GF_IO_ERR; gf_list_add(ftpriv->loaded_fonts, face); ftpriv->active_face = face; return GF_OK; } if (checkStyles){ /* If we tried font + bold + italic -> we will try font + [bold | italic] If we tried font + [bold | italic] -> we try font */ if (checkStyles == (GF_FONT_WEIGHT_BOLD | GF_FONT_ITALIC)) checkStyles = GF_FONT_WEIGHT_BOLD; else if (checkStyles == GF_FONT_WEIGHT_BOLD && (styles & GF_FONT_ITALIC)) checkStyles = GF_FONT_ITALIC; else if (checkStyles == GF_FONT_WEIGHT_BOLD || checkStyles == GF_FONT_ITALIC) checkStyles = 0; goto checkFont; } } GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[FreeType] Font '%s' (%s) not found\n", fontName, fname)); gf_free(fname); return GF_NOT_SUPPORTED; }
void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs) { char sLine[2000]; char token[100]; char *p; X3DNode *n; X3DField *f; u32 j, i, k; //get lines one by one n = NULL; while (!feof(nodes)) { fgets(sLine, 2000, nodes); //skip comment and empty lines if (sLine[0] == '#') continue; if (sLine[0] == '\n') continue; CurrentLine = sLine; //parse the line till end of line while (GetNextToken(token, " \t")) { //this is a new node if (!strcmp(token, "PROTO") ) { n = BlankNode(); gf_list_add(BNodes, n); //get its name GetNextToken(n->name, " \t["); //extract the NDTs GetNextToken(token, "\t[ %#="); if (strcmp(token, "NDT")) { printf("Corrupted template file\n"); return; } while (1) { GetNextToken(token, "=, \t"); //done with NDTs if (!token[0]) break; //update the NDT list CheckInTable(token, NDTs); p = gf_malloc(strlen(token)+1); strcpy(p, token); gf_list_add(n->NDT, p); } } //this is NOT a field else if (token[0] == ']' || token[0] == '{' || token[0] == '}' ) { break; } //parse a field else { if (!n) { printf("Corrupted template file\n"); return; } f = BlankField(); gf_list_add(n->Fields, f); //get the field type strcpy(f->type, token); GetNextToken(f->familly, " \t"); GetNextToken(f->name, " \t"); //fix for our own code :( if (!strcmp(f->name, "tag")) strcpy(f->name, "_tag"); //has default skip_sep(" \t"); if (GetNextToken(token, "#\t")) { j=0; while (token[j] == ' ') j+=1; if (token[j] == '[') j+=1; if (token[j] == '"') j+=1; if (token[j] != '"' && token[j] != ']') { strcpy(f->def, token+j); j=1; while (j) { switch (f->def[strlen(f->def)-1]) { case ' ': case '"': case ']': f->def[strlen(f->def)-1] = 0; break; default: j=0; break; } } } else { strcpy(f->def, ""); } if (!strcmp(f->familly, "SFFloat")) { if (!strcmp(f->def, "+I") || !strcmp(f->def, "I")) { strcpy(f->def, "GF_MAX_FLOAT"); } else if (!strcmp(f->def, "-I")) { strcpy(f->def, "GF_MIN_FLOAT"); } } else if (!strcmp(f->familly, "SFTime")) { if (!strcmp(f->def, "+I") || !strcmp(f->def, "I")) { strcpy(f->def, "GF_MAX_FLOAT"); } else if (!strcmp(f->def, "-I")) { strcpy(f->def, "GF_MIN_FLOAT"); } } else if (!strcmp(f->familly, "SFInt32")) { if (!strcmp(f->def, "+I") || !strcmp(f->def, "I")) { strcpy(f->def, "2 << 31"); } else if (!strcmp(f->def, "-I")) { strcpy(f->def, "- (2 << 31)"); } } } //has other while (GetNextToken(token, " \t#%=")) { switch (token[0]) { //bounds case 'b': case 'q': case 'a': printf("Corrupted X3D template file (quantization/animation not allowed)\n"); gf_list_del_item(n->Fields, f); gf_free(f); return; default: break; } } /*we ignore these*/ if (!stricmp(f->name, "bboxCenter") || !stricmp(f->name, "bboxSize")) { gf_list_del_item(n->Fields, f); gf_free(f); } } } } for (k=0; k<gf_list_count(BNodes); k++) { n = gf_list_get(BNodes, k); for (i=0; i<gf_list_count(n->Fields); i++) { f = gf_list_get(n->Fields, i); //nothing on events if (!strcmp(f->type, "eventIn")) continue; if (!strcmp(f->type, "eventOut")) continue; if (!strcmp(f->def, "")) continue; if (strstr(f->familly, "Node")) continue; n->hasDefault = 1; } } }
static GF_Err BM_XReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { GF_FieldInfo targetField, fromField, decfield; GF_Node *target, *n, *fromNode; s32 pos = -2; u32 id, nbBits, ind, aind; GF_Err e; GF_Command *com; GF_CommandField *inf; id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); target = gf_sg_find_node(codec->current_graph, id); if (!target) return GF_SG_UNKNOWN_NODE; e = GF_OK; com = gf_sg_command_new(codec->current_graph, GF_SG_XREPLACE); BM_SetCommandNode(com, target); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1); ind = gf_bs_read_int(bs, nbBits); e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind); if (e) return e; e = gf_node_get_field(target, aind, &targetField); if (e) return e; inf = gf_sg_command_field_new(com); inf->fieldIndex = aind; if (!gf_sg_vrml_is_sf_field(targetField.fieldType)) { /*this is indexed replacement*/ if (gf_bs_read_int(bs, 1)) { /*index is dynamic*/ if (gf_bs_read_int(bs, 1)) { id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); n = gf_sg_find_node(codec->current_graph, id); if (!n) return GF_SG_UNKNOWN_NODE; com->toNodeID = id; nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); ind = gf_bs_read_int(bs, nbBits); e = gf_bifs_get_field_index(n, ind, GF_SG_FIELD_CODING_DEF, &aind); if (e) return e; e = gf_node_get_field(n, aind, &fromField); if (e) return e; com->toFieldIndex = aind; } else { u32 type = gf_bs_read_int(bs, 2); switch (type) { case 0: pos = gf_bs_read_int(bs, 16); break; case 2: pos = 0; break; case 3: pos = -1; break; } } } if (targetField.fieldType==GF_SG_VRML_MFNODE) { if (gf_bs_read_int(bs, 1)) { target = gf_node_list_get_child(*(GF_ChildNodeItem **)targetField.far_ptr, pos); if (!target) return GF_SG_UNKNOWN_NODE; nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1); ind = gf_bs_read_int(bs, nbBits); e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind); if (e) return e; e = gf_node_get_field(target, aind, &targetField); if (e) return e; pos = -2; com->child_field = aind; com->ChildNodeTag = gf_node_get_tag(target); if (com->ChildNodeTag == TAG_ProtoNode) { s32 p_id = gf_sg_proto_get_id(gf_node_get_proto(target)); com->ChildNodeTag = -p_id; } } } inf->pos = pos; } fromNode = NULL; if (gf_bs_read_int(bs, 1)) { id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); fromNode = gf_sg_find_node(codec->current_graph, id); if (!fromNode) return GF_SG_UNKNOWN_NODE; com->fromNodeID = id; nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(fromNode, GF_SG_FIELD_CODING_DEF)-1); ind = gf_bs_read_int(bs, nbBits); e = gf_bifs_get_field_index(fromNode, ind, GF_SG_FIELD_CODING_DEF, &aind); if (e) return e; e = gf_node_get_field(fromNode, aind, &fromField); if (e) return e; com->fromFieldIndex = aind; return GF_OK; } if (pos>= -1) { inf->fieldType = gf_sg_vrml_get_sf_type(targetField.fieldType); } else { inf->fieldType = targetField.fieldType; } decfield.fieldIndex = inf->fieldIndex; decfield.fieldType = inf->fieldType; if (inf->fieldType==GF_SG_VRML_SFNODE) { decfield.far_ptr = inf->field_ptr = &inf->new_node; } else if (inf->fieldType==GF_SG_VRML_MFNODE) { decfield.far_ptr = inf->field_ptr = &inf->node_list; } else { decfield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); } e = gf_bifs_dec_sf_field(codec, bs, target, &decfield, 1); if (e) return e; gf_list_add(com_list, com); return GF_OK; }
int dc_read_switch_config(CmdData *cmd_data) { u32 i; int src_number; char start_time[4096], end_time[4096]; time_t now_t = time(NULL); struct tm start_tm = *localtime(&now_t); struct tm end_tm = *localtime(&now_t); GF_Config *conf = cmd_data->switch_conf; u32 sec_count = gf_cfg_get_section_count(conf); dc_task_init(&cmd_data->task_list); if (sec_count == 0) { return 0; } for (i = 0; i < sec_count; i++) { const char *section_name = gf_cfg_get_section_name(conf, i); const char *section_type = gf_cfg_get_key(conf, section_name, "type"); if (strcmp(section_type, "video") == 0) { VideoDataConf *video_data_conf = gf_malloc(sizeof(VideoDataConf)); strcpy(video_data_conf->source_id, section_name); strcpy(video_data_conf->filename, gf_cfg_get_key(conf, section_name, "source")); strcpy(start_time, gf_cfg_get_key(conf, section_name, "start")); parse_time(start_time, &start_tm); video_data_conf->start_time = mktime(&start_tm); strcpy(end_time, gf_cfg_get_key(conf, section_name, "end")); parse_time(end_time, &end_tm); video_data_conf->end_time = mktime(&end_tm); gf_list_add(cmd_data->vsrc, (void *) video_data_conf); src_number = gf_list_count(cmd_data->vsrc); dc_task_add(&cmd_data->task_list, src_number, video_data_conf->source_id, video_data_conf->start_time, video_data_conf->end_time); } else if (strcmp(section_type, "audio") == 0) { AudioDataConf *audio_data_conf = gf_malloc(sizeof(AudioDataConf)); strcpy(audio_data_conf->source_id, section_name); strcpy(audio_data_conf->filename, gf_cfg_get_key(conf, section_name, "source")); strcpy(start_time, gf_cfg_get_key(conf, section_name, "start")); parse_time(start_time, &start_tm); audio_data_conf->start_time = mktime(&start_tm); strcpy(end_time, gf_cfg_get_key(conf, section_name, "end")); parse_time(end_time, &end_tm); audio_data_conf->end_time = mktime(&end_tm); gf_list_add(cmd_data->asrc, (void *) audio_data_conf); } else { fprintf(stdout, "Switch source configuration file: type %s is not supported.\n", section_type); } } fprintf(stdout, "\33[34m\33[1m"); fprintf(stdout, "Sources:\n"); for (i=0; i<gf_list_count(cmd_data->vsrc); i++) { VideoDataConf *video_data_conf = gf_list_get(cmd_data->vsrc, i); strftime(start_time, 20, "%Y-%m-%d %H:%M:%S", localtime(&video_data_conf->start_time)); strftime(end_time, 20, "%Y-%m-%d %H:%M:%S", localtime(&video_data_conf->end_time)); fprintf(stdout, " id:%s\tsource:%s\tstart:%s\tend:%s\n", video_data_conf->source_id, video_data_conf->filename, start_time, end_time); } for (i=0; i<gf_list_count(cmd_data->asrc); i++) { AudioDataConf *audio_data_conf = gf_list_get(cmd_data->asrc, i); strftime(start_time, 20, "%Y-%m-%d %H:%M:%S", localtime(&audio_data_conf->start_time)); strftime(end_time, 20, "%Y-%m-%d %H:%M:%S", localtime(&audio_data_conf->end_time)); fprintf(stdout, " id:%s\tsource:%s\tstart:%s\tend:%s\n", audio_data_conf->source_id, audio_data_conf->filename, start_time, end_time); } fprintf(stdout, "\33[0m"); fflush(stdout); return 0; }
/*NB This can insert a node as well (but usually not in the .children field)*/ GF_Err BM_ParseIndexInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { GF_Err e; u32 NodeID; u32 NumBits, ind, field_ind; u8 type; GF_Command *com; GF_CommandField *inf; s32 pos; GF_Node *def, *node; GF_FieldInfo field, sffield; NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); def = gf_sg_find_node(codec->current_graph, NodeID); if (!def) return GF_NON_COMPLIANT_BITSTREAM; /*index insertion uses IN mode for field index*/ NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(def, GF_SG_FIELD_CODING_IN)-1); ind = gf_bs_read_int(bs, NumBits); e = gf_bifs_get_field_index(def, ind, GF_SG_FIELD_CODING_IN, &field_ind); if (e) return e; type = gf_bs_read_int(bs, 2); switch (type) { case 0: pos = gf_bs_read_int(bs, 16); break; case 2: pos = 0; break; case 3: pos = -1; break; default: return GF_NON_COMPLIANT_BITSTREAM; } e = gf_node_get_field(def, field_ind, &field); if (e) return e; if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; memcpy(&sffield, &field, sizeof(GF_FieldInfo)); sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); /*rescale the MFField and parse the SFField*/ if (field.fieldType==GF_SG_VRML_MFNODE) { node = gf_bifs_dec_node(codec, bs, field.NDTtype); if (!codec->LastError) { com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT); BM_SetCommandNode(com, def); inf = gf_sg_command_field_new(com); inf->pos = pos; inf->fieldIndex = field_ind; inf->fieldType = sffield.fieldType; inf->new_node = node; inf->field_ptr = &inf->new_node; gf_list_add(com_list, com); /*register*/ gf_node_register(node, NULL); } } else { com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT); BM_SetCommandNode(com, def); inf = gf_sg_command_field_new(com); inf->pos = pos; inf->fieldIndex = field_ind; inf->fieldType = sffield.fieldType; sffield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(sffield.fieldType); codec->LastError = gf_bifs_dec_sf_field(codec, bs, def, &sffield, 1); gf_list_add(com_list, com); } return codec->LastError; }
void RP_SaveSessionState(RTPClient *rtp) { GF_Err e; char *sdp_buf; const char *opt; GF_X_Attribute*att; u32 i, j; GF_SDPInfo *sdp; RTSPSession *sess = NULL; if (!rtp->session_state_data) return; sdp_buf = rtp->session_state_data + strlen("data:application/sdp,"); sdp = gf_sdp_info_new(); e = gf_sdp_info_parse(sdp, sdp_buf, (u32) strlen(sdp_buf) ); for (i=0; i<gf_list_count(rtp->channels); i++) { GF_SDPMedia *media = NULL; RTPStream *ch = gf_list_get(rtp->channels, i); if (!ch->control) continue; for (j=0; j<gf_list_count(sdp->media_desc); j++) { u32 k; GF_SDPMedia *med = (GF_SDPMedia*)gf_list_get(sdp->media_desc, j); for (k=0; k<gf_list_count(med->Attributes); k++) { att = (GF_X_Attribute*)gf_list_get(med->Attributes, k); if (!stricmp(att->Name, "control") && (strstr(att->Value, ch->control)!=NULL) ) { media = med; break; } } if (media) break; } if (!media) continue; if (ch->rtp_ch->net_info.IsUnicast) { char szPorts[4096]; u16 porta, portb; media->PortNumber = ch->rtp_ch->net_info.client_port_first; /*remove x-server-port extension*/ for (j=0; j<gf_list_count(media->Attributes); j++) { att = (GF_X_Attribute*)gf_list_get(media->Attributes, j); if (!stricmp(att->Name, "x-stream-state") ) { gf_free(att->Name); gf_free(att->Value); gf_free(att); gf_list_rem(media->Attributes, j); } } ch->current_start += gf_rtp_get_current_time(ch->rtp_ch); GF_SAFEALLOC(att, GF_X_Attribute); att->Name = gf_strdup("x-stream-state"); porta = ch->rtp_ch->net_info.port_first ? ch->rtp_ch->net_info.port_first : ch->rtp_ch->net_info.client_port_first; portb = ch->rtp_ch->net_info.port_last ? ch->rtp_ch->net_info.port_last : ch->rtp_ch->net_info.client_port_last; sprintf(szPorts, "server-port=%d-%d;ssrc=%X;npt=%g;seq=%d;rtptime=%d", porta, portb, ch->rtp_ch->SenderSSRC, ch->current_start, ch->rtp_ch->rtp_first_SN, ch->rtp_ch->rtp_time ); att->Value = gf_strdup(szPorts); gf_list_add(media->Attributes, att); if (ch->rtsp) sess = ch->rtsp; } else { media->PortNumber = ch->rtp_ch->net_info.port_first; } } /*remove x-server-port/x-session-id extension*/ for (j=0; j<gf_list_count(sdp->Attributes); j++) { att = (GF_X_Attribute*)gf_list_get(sdp->Attributes, j); if (!stricmp(att->Name, "x-session-id") || !stricmp(att->Name, "x-session-name") ) { gf_free(att->Name); gf_free(att->Value); gf_free(att); gf_list_rem(sdp->Attributes, j); } } if (sess) { char szURL[4096]; if (sess->session_id) { GF_SAFEALLOC(att, GF_X_Attribute); att->Name = gf_strdup("x-session-id"); att->Value = gf_strdup(sess->session_id); gf_list_add(sdp->Attributes, att); } GF_SAFEALLOC(att, GF_X_Attribute); att->Name = gf_strdup("x-session-name"); sprintf(szURL, "rtsp://%s:%d/%s", sess->session->Server, sess->session->Port, sess->session->Service); att->Value = gf_strdup(szURL); gf_list_add(sdp->Attributes, att); } gf_free(rtp->session_state_data); sdp_buf = NULL; gf_sdp_info_write(sdp, &sdp_buf); if (sdp_buf) { rtp->session_state_data = gf_malloc(sizeof(char) * (strlen("data:application/sdp,") + strlen(sdp_buf) + 1) ); strcpy(rtp->session_state_data, "data:application/sdp,"); strcat(rtp->session_state_data, sdp_buf); gf_free(sdp_buf); } gf_sdp_info_del(sdp); opt = (char *) gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(rtp->service), "Streaming", "SessionMigrationServer"); if (opt) { if (rtp->dnload) gf_term_download_del(rtp->dnload); rtp->dnload = NULL; if (strnicmp(opt, "http://", 7)) { rtp->dnload = gf_term_download_new(rtp->service, opt, GF_NETIO_SESSION_NOT_THREADED, MigrateSDP_NetIO, rtp); while (1) { char buffer[100]; u32 read; e = gf_dm_sess_fetch_data(rtp->dnload, buffer, 100, &read); if (e && (e!=GF_IP_NETWORK_EMPTY)) break; } gf_term_download_del(rtp->dnload); rtp->dnload = NULL; } else { FILE *f = gf_f64_open(opt, "wt"); if (f) { sdp_buf = rtp->session_state_data + strlen("data:application/sdp,"); gf_fwrite(sdp_buf, 1, strlen(sdp_buf), f); fclose(f); } else { e = GF_IO_ERR; } } if (e<0) { gf_term_on_message(sess->owner->service, e, "Error saving session state"); } } }
static GF_Err BM_ParseMultipleReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { u32 i, numFields, index, flag, nbBits, field_ref, fieldind; GF_Err e; GF_FieldInfo field; u32 NodeID; GF_Node *node; GF_Command *com; GF_CommandField *inf; NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); node = gf_sg_find_node(codec->current_graph, NodeID); if (!node) return GF_NON_COMPLIANT_BITSTREAM; e = GF_OK; com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_REPLACE); BM_SetCommandNode(com, node); flag = gf_bs_read_int(bs, 1); if (flag) { numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF); for (i=0; i<numFields; i++) { flag = gf_bs_read_int(bs, 1); if (!flag) continue; gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &index); e = gf_node_get_field(node, index, &field); if (e) goto exit; inf = gf_sg_command_field_new(com); inf->fieldType = field.fieldType; inf->fieldIndex = field.fieldIndex; if (inf->fieldType==GF_SG_VRML_SFNODE) { field.far_ptr = inf->field_ptr = &inf->new_node; } else if (inf->fieldType==GF_SG_VRML_MFNODE) { field.far_ptr = inf->field_ptr = &inf->node_list; } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); } e = gf_bifs_dec_field(codec, bs, node, &field, 1); if (e) goto exit; } } else { flag = gf_bs_read_int(bs, 1); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1); while (!flag && (codec->LastError>=0)) { field_ref = gf_bs_read_int(bs, nbBits); e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &fieldind); if (e) goto exit; e = gf_node_get_field(node, fieldind, &field); if (e) goto exit; inf = gf_sg_command_field_new(com); inf->fieldType = field.fieldType; inf->fieldIndex = field.fieldIndex; if (inf->fieldType==GF_SG_VRML_SFNODE) { field.far_ptr = inf->field_ptr = &inf->new_node; } else if (inf->fieldType==GF_SG_VRML_MFNODE) { field.far_ptr = inf->field_ptr = &inf->node_list; } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); } e = gf_bifs_dec_field(codec, bs, node, &field, 1); if (e) goto exit; flag = gf_bs_read_int(bs, 1); } } exit: if (e) gf_sg_command_del(com); else gf_list_add(com_list, com); return e; }
static void TraverseViewpoint(GF_Node *node, void *rs, Bool is_destroy) { SFVec3f pos, v1, v2; SFRotation ori; GF_Matrix mx; GF_TraverseState *tr_state = (GF_TraverseState *)rs; M_Viewpoint *vp = (M_Viewpoint*) node; ViewStack *st = (ViewStack *) gf_node_get_private(node); if (is_destroy) { DestroyViewStack(node); return; } /*may happen in get_bounds*/ if (!tr_state->viewpoints) return; // if (!tr_state->camera->is_3D) return; /*first traverse, bound if needed*/ if (gf_list_find(tr_state->viewpoints, node) < 0) { gf_list_add(tr_state->viewpoints, node); assert(gf_list_find(st->reg_stacks, tr_state->viewpoints)==-1); gf_list_add(st->reg_stacks, tr_state->viewpoints); if (gf_list_get(tr_state->viewpoints, 0) == vp) { if (!vp->isBound) Bindable_SetIsBound(node, 1); } else { if (gf_inline_is_default_viewpoint(node)) Bindable_SetSetBind(node, 1); } VPCHANGED(tr_state->visual->compositor); /*in any case don't draw the first time (since the viewport could have been declared last)*/ if (tr_state->layer3d) gf_node_dirty_set(tr_state->layer3d, GF_SG_VRML_BINDABLE_DIRTY, 0); gf_sc_invalidate(tr_state->visual->compositor, NULL); } /*not evaluating vp, return*/ if (tr_state->traversing_mode != TRAVERSE_BINDABLE) { /*store model matrix if changed - NOTE: we always have a 1-frame delay between VP used and real world... we could remove this by pre-traversing the scene before applying vp, but that would mean 2 scene traversals*/ if ((tr_state->traversing_mode==TRAVERSE_SORT) || (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) ) { if (!gf_mx_equal(&st->world_view_mx, &tr_state->model_matrix)) { gf_mx_copy(st->world_view_mx, tr_state->model_matrix); gf_node_dirty_set(node, 0, 0); } } return; } /*not bound or in 2D visual*/ if (!vp->isBound || !tr_state->navigations) return; if (!gf_node_dirty_get(node)) { if ((tr_state->vp_size.x == st->last_vp_size.x) && (tr_state->vp_size.y == st->last_vp_size.y)) return; } gf_node_dirty_clear(node, 0); st->last_vp_size.x = tr_state->vp_size.x; st->last_vp_size.y = tr_state->vp_size.y; /*move to local system*/ gf_mx_copy(mx, st->world_view_mx); gf_mx_add_translation(&mx, vp->position.x, vp->position.y, vp->position.z); gf_mx_add_rotation(&mx, vp->orientation.q, vp->orientation.x, vp->orientation.y, vp->orientation.z); gf_mx_decompose(&mx, &pos, &v1, &ori, &v2); /*get center*/ v1.x = v1.y = v1.z = 0; #ifndef GPAC_DISABLE_X3D /*X3D specifies examine center*/ if (gf_node_get_tag(node)==TAG_X3D_Viewpoint) v1 = ((X_Viewpoint *)node)->centerOfRotation; #endif gf_mx_apply_vec(&st->world_view_mx, &v1); /*set frustrum param - animate only if not bound last frame and jump false*/ visual_3d_viewpoint_change(tr_state, node, (!st->prev_was_bound && !vp->jump) ? 1 : 0, vp->fieldOfView, pos, ori, v1); st->prev_was_bound = 1; }
static void TraverseNavigationInfo(GF_Node *node, void *rs, Bool is_destroy) { u32 i, nb_select_mode; #ifndef GPAC_DISABLE_3D SFVec3f start, end; Fixed scale; ViewStack *st = (ViewStack *) gf_node_get_private(node); #endif GF_TraverseState *tr_state = (GF_TraverseState *)rs; M_NavigationInfo *ni = (M_NavigationInfo *) node; if (is_destroy) { DestroyViewStack(node); return; } #ifdef GPAC_DISABLE_3D /*FIXME, we only deal with one node, no bind stack for the current time*/ for (i=0; i<ni->type.count; i++) { if (ni->type.vals[i] && !stricmp(ni->type.vals[i], "NONE")) { tr_state->visual->compositor->navigation_disabled = 1; } } #else if (!tr_state->navigations) return; /*first traverse, bound if needed*/ if (gf_list_find(tr_state->navigations, node) < 0) { gf_list_add(tr_state->navigations, node); if (gf_list_get(tr_state->navigations, 0) == ni) { if (!ni->isBound) Bindable_SetIsBound(node, 1); } assert(gf_list_find(st->reg_stacks, tr_state->navigations)==-1); gf_list_add(st->reg_stacks, tr_state->navigations); gf_mx_copy(st->world_view_mx, tr_state->model_matrix); /*in any case don't draw the first time*/ gf_sc_invalidate(tr_state->visual->compositor, NULL); return; } /*not bound*/ if (!ni->isBound) return; /*not evaluating, return*/ if (tr_state->traversing_mode != TRAVERSE_BINDABLE) { if ((tr_state->traversing_mode==TRAVERSE_SORT) || (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) ) { if (!gf_mx_equal(&st->world_view_mx, &tr_state->model_matrix)) { gf_mx_copy(st->world_view_mx, tr_state->model_matrix); gf_node_dirty_set(node, 0, 0); } } return; } if (!gf_node_dirty_get(node)) return; gf_node_dirty_clear(node, 0); nb_select_mode = 0; tr_state->camera->navigation_flags = 0; tr_state->camera->navigate_mode = 0; for (i=0; i<ni->type.count; i++) { if (ni->type.vals[i] && !stricmp(ni->type.vals[i], "ANY")) tr_state->camera->navigation_flags |= NAV_ANY; else { nb_select_mode++; } if (!tr_state->camera->navigate_mode) { if (ni->type.vals[i] && !stricmp(ni->type.vals[i], "NONE")) tr_state->camera->navigate_mode = GF_NAVIGATE_NONE; else if (ni->type.vals[i] && !stricmp(ni->type.vals[i], "WALK")) tr_state->camera->navigate_mode = GF_NAVIGATE_WALK; else if (ni->type.vals[i] && !stricmp(ni->type.vals[i], "EXAMINE")) tr_state->camera->navigate_mode = GF_NAVIGATE_EXAMINE; else if (ni->type.vals[i] && !stricmp(ni->type.vals[i], "FLY")) tr_state->camera->navigate_mode = GF_NAVIGATE_FLY; else if (ni->type.vals[i] && !stricmp(ni->type.vals[i], "VR")) tr_state->camera->navigate_mode = GF_NAVIGATE_VR; } } if (nb_select_mode>1) tr_state->camera->navigation_flags |= NAV_SELECTABLE; if (ni->headlight) tr_state->camera->navigation_flags |= NAV_HEADLIGHT; start.x = start.y = start.z = 0; end.x = end.y = 0; end.z = FIX_ONE; gf_mx_apply_vec(&st->world_view_mx, &start); gf_mx_apply_vec(&st->world_view_mx, &end); gf_vec_diff(end, end, start); scale = gf_vec_len(end); tr_state->camera->speed = gf_mulfix(scale, ni->speed); tr_state->camera->visibility = gf_mulfix(scale, ni->visibilityLimit); if (ni->avatarSize.count) tr_state->camera->avatar_size.x = gf_mulfix(scale, ni->avatarSize.vals[0]); if (ni->avatarSize.count>1) tr_state->camera->avatar_size.y = gf_mulfix(scale, ni->avatarSize.vals[1]); if (ni->avatarSize.count>2) tr_state->camera->avatar_size.z = gf_mulfix(scale, ni->avatarSize.vals[2]); if (0 && tr_state->pixel_metrics) { u32 s = MAX(tr_state->visual->width, tr_state->visual->height); s /= 2; // tr_state->camera->speed = ni->speed; tr_state->camera->visibility *= s; tr_state->camera->avatar_size.x *= s; tr_state->camera->avatar_size.y *= s; tr_state->camera->avatar_size.z *= s; } #endif }