GF_Err BE_RouteReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs, Bool isInsert) { GF_Err e; GF_Node *n; u32 numBits, ind; if (isInsert) { GF_BIFS_WRITE_INT(codec, bs, com->RouteID ? 1 : 0, 1, "isDEF", NULL); if (com->RouteID) { GF_BIFS_WRITE_INT(codec, bs, com->RouteID-1, codec->info->config.RouteIDBits, "RouteID", NULL); if (codec->UseName) gf_bifs_enc_name(codec, bs, com->def_name); } } else { GF_BIFS_WRITE_INT(codec, bs, com->RouteID - 1, codec->info->config.RouteIDBits, "RouteID", NULL); } /*origin*/ GF_BIFS_WRITE_INT(codec, bs, com->fromNodeID - 1, codec->info->config.NodeIDBits, "outNodeID", NULL); n = gf_bifs_enc_find_node(codec, com->fromNodeID); numBits = gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_OUT) - 1; numBits = gf_get_bit_size(numBits); e = gf_bifs_field_index_by_mode(n, com->fromFieldIndex, GF_SG_FIELD_CODING_OUT, &ind); if (e) return e; GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "outField", NULL); /*target*/ GF_BIFS_WRITE_INT(codec, bs, com->toNodeID - 1, codec->info->config.NodeIDBits, "inNodeID", NULL); n = gf_bifs_enc_find_node(codec, com->toNodeID); numBits = gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_IN) - 1; numBits = gf_get_bit_size(numBits); e = gf_bifs_field_index_by_mode(n, com->toFieldIndex, GF_SG_FIELD_CODING_IN, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "inField", NULL); return e; }
GF_Err gf_bifs_enc_route(GF_BifsEncoder *codec, GF_Route *r, GF_BitStream *bs) { GF_Err e; u32 numBits, ind; if (!r) return GF_BAD_PARAM; GF_BIFS_WRITE_INT(codec, bs, r->ID ? 1: 0, 1, "isDEF", NULL); /*def'ed route*/ if (r->ID) { GF_BIFS_WRITE_INT(codec, bs, r->ID-1, codec->info->config.RouteIDBits, "routeID", NULL); if (codec->UseName) gf_bifs_enc_name(codec, bs, r->name); } /*origin*/ GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(r->FromNode) - 1, codec->info->config.NodeIDBits, "outNodeID", NULL); numBits = gf_node_get_num_fields_in_mode(r->FromNode, GF_SG_FIELD_CODING_OUT) - 1; numBits = gf_get_bit_size(numBits); e = gf_bifs_field_index_by_mode(r->FromNode, r->FromField.fieldIndex, GF_SG_FIELD_CODING_OUT, &ind); if (e) return e; GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "outField", NULL); /*target*/ GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(r->ToNode) - 1, codec->info->config.NodeIDBits, "inNodeID", NULL); numBits = gf_node_get_num_fields_in_mode(r->ToNode, GF_SG_FIELD_CODING_IN) - 1; numBits = gf_get_bit_size(numBits); e = gf_bifs_field_index_by_mode(r->ToNode, r->ToField.fieldIndex, GF_SG_FIELD_CODING_IN, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "inField", NULL); return e; }
GF_Err gf_bifs_dec_node_list(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, Bool is_proto) { u8 flag; GF_Err e; u32 numBitsALL, numBitsDEF, field_all, field_ref, numProtoBits; GF_FieldInfo field; e = GF_OK; numProtoBits = numBitsALL = 0; if (codec->pCurrentProto) { numProtoBits = gf_get_bit_size(gf_sg_proto_get_field_count(codec->pCurrentProto) - 1); numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL)-1); } numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1); flag = gf_bs_read_int(bs, 1); while (!flag && (codec->LastError>=0)) { if (codec->pCurrentProto) { //IS'ed flag flag = gf_bs_read_int(bs, 1); if (flag) { //get field index in ALL mode for node field_ref = gf_bs_read_int(bs, numBitsALL); //get field index in ALL mode for proto field_all = gf_bs_read_int(bs, numProtoBits); e = gf_node_get_field(node, field_ref, &field); if (e) return e; e = BD_SetProtoISed(codec, field_all, node, field_ref); if (e) return e; flag = gf_bs_read_int(bs, 1); continue; } } //fields are coded in DEF mode field_ref = gf_bs_read_int(bs, numBitsDEF); e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &field_all); if (e) return e; e = gf_node_get_field(node, field_all, &field); if (e) return e; e = gf_bifs_dec_field(codec, bs, node, &field, 0); if (e) return e; flag = gf_bs_read_int(bs, 1); if (is_proto) gf_sg_proto_mark_field_loaded(node, &field); } return codec->LastError; }
GF_Err BM_ParseRouteInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { GF_Err e; u8 flag; GF_Command *com; GF_Node *InNode, *OutNode; u32 RouteID, outField, inField, numBits, ind, node_id; char name[1000]; RouteID = 0; flag = gf_bs_read_int(bs, 1); /*def'ed route*/ if (flag) { RouteID = 1 + gf_bs_read_int(bs, codec->info->config.RouteIDBits); if (codec->UseName) gf_bifs_dec_name(bs, name); } /*origin*/ node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); OutNode = gf_sg_find_node(codec->current_graph, node_id); if (!OutNode) return GF_SG_UNKNOWN_NODE; numBits = gf_node_get_num_fields_in_mode(OutNode, GF_SG_FIELD_CODING_OUT) - 1; numBits = gf_get_bit_size(numBits); ind = gf_bs_read_int(bs, numBits); e = gf_bifs_get_field_index(OutNode, ind, GF_SG_FIELD_CODING_OUT, &outField); /*target*/ node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); InNode = gf_sg_find_node(codec->current_graph, node_id); if (!InNode) return GF_SG_UNKNOWN_NODE; numBits = gf_node_get_num_fields_in_mode(InNode, GF_SG_FIELD_CODING_IN) - 1; numBits = gf_get_bit_size(numBits); ind = gf_bs_read_int(bs, numBits); e = gf_bifs_get_field_index(InNode, ind, GF_SG_FIELD_CODING_IN, &inField); if (e) return e; com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_INSERT); com->RouteID = RouteID; if (codec->UseName) com->def_name = gf_strdup( name); com->fromNodeID = gf_node_get_id(OutNode); com->fromFieldIndex = outField; com->toNodeID = gf_node_get_id(InNode); com->toFieldIndex = inField; gf_list_add(com_list, com); return codec->LastError; }
GF_Err BE_IndexDelete(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) { u32 NumBits, ind; GF_Err e; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN) - 1); e = gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); if (e) return e; GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); switch (inf->pos) { case 0: GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idw"); break; case -1: GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx"); break; default: GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx"); GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL); break; } return GF_OK; }
void gp_rtp_builder_set_cryp_info(GP_RTPPacketizer *builder, u64 IV, char *key_indicator, Bool is_encrypted) { if (!key_indicator) { if (builder->key_indicator) { /*force flush if no provision for keyIndicator per AU*/ builder->force_flush = (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU) ? 0 : 1; gf_free(builder->key_indicator); builder->key_indicator = NULL; } } else if (!builder->key_indicator || memcmp(builder->key_indicator, key_indicator, sizeof(char)*builder->slMap.KI_length) ) { /*force flush if no provision for keyIndicator per AU*/ builder->force_flush = (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU) ? 0 : 1; if (!builder->key_indicator) builder->key_indicator = (char *) gf_malloc(sizeof(char)*builder->slMap.KI_length); memcpy(builder->key_indicator, key_indicator, sizeof(char)*builder->slMap.KI_length); } if (builder->IV != IV) { builder->IV = IV; if (builder->slMap.IV_delta_length && (builder->slMap.IV_delta_length < gf_get_bit_size((u32) (IV - builder->first_AU_IV) ))) { builder->first_AU_IV = IV; builder->force_flush = 1; } } builder->is_encrypted = is_encrypted; }
GF_Err BE_FieldReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) { GF_Err e; u32 ind, NumBits; GF_FieldInfo field; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; field.far_ptr = inf->field_ptr; /* Warning: To be changed when proper solution is found */ if (gf_sg_vrml_get_sf_type(field.fieldType) == GF_SG_VRML_SFSCRIPT) codec->is_encoding_command = 1; e = gf_bifs_enc_field(codec, bs, com->node, &field); codec->is_encoding_command = 0; return e; }
u32 RunHTKDec(void *par) { GF_BitStream *bs; char *szWord; s32 word_index; u32 len, val, i; Float word_score; GF_SLHeader slh; GF_Codec *cod; unsigned char *buf; u32 buf_size; ISPriv *is_dec = (ISPriv *)par; // while (is_dec->htk_running) HTK_DoDetection(); szWord = HTK_GetWord(); word_index = HTK_GetWordIndex(); word_score = HTK_GetWordScore(); bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*HTK sensor buffer format: SFString - SFInt32 - SFFloat*/ gf_bs_write_int(bs, 1, 1); len = strlen(szWord); val = gf_get_bit_size(len); gf_bs_write_int(bs, val, 5); gf_bs_write_int(bs, len, val); for (i=0; i<len; i++) gf_bs_write_int(bs, szWord[i], 8); gf_bs_write_int(bs, 1, 1); gf_bs_write_int(bs, word_index, 32); gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, word_score); gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); memset(&slh, 0, sizeof(GF_SLHeader)); slh.accessUnitStartFlag = slh.accessUnitEndFlag = 1; slh.compositionTimeStamp = 0; /*get all IS keySensor decoders and send frame*/ i=0; while ((cod = gf_list_enum(is_dec->scene->root_od->term->input_streams, &i))) { ISPriv *is = cod->decio->privateStack; if (is != is_dec) continue; if (is->type==IS_HTKSensor) { GF_Channel *ch = gf_list_get(cod->inChannels, 0); gf_es_receive_sl_packet(ch->service, ch, buf, buf_size, &slh, GF_OK); } } free(buf); is_dec->htk_running = 0; return 0; }
GF_Err BM_ParseIndexValueReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { u32 NodeID, ind, field_ind, NumBits; s32 type, pos; GF_Command *com; GF_Node *node; GF_Err e; GF_FieldInfo field, sffield; GF_CommandField *inf; /*get the node*/ 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; NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1); ind = gf_bs_read_int(bs, NumBits); e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind); if (e) return e; e = gf_node_get_field(node, field_ind, &field); if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; 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 = ((GenMFField *) field.far_ptr)->count - 1; break; default: return GF_NON_COMPLIANT_BITSTREAM; } com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_REPLACE); BM_SetCommandNode(com, node); inf = gf_sg_command_field_new(com); inf->fieldIndex = field.fieldIndex; inf->pos = pos; if (field.fieldType == GF_SG_VRML_MFNODE) { inf->fieldType = GF_SG_VRML_SFNODE; inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype); inf->field_ptr = &inf->new_node; if (inf->new_node) gf_node_register(inf->new_node, NULL); } else { memcpy(&sffield, &field, sizeof(GF_FieldInfo)); sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); 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, node, &sffield, 1); } gf_list_add(com_list, com); return codec->LastError; }
static GF_Err BE_MultipleIndexedReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { u32 i,nbBits, count, maxPos, nbBitsPos; GF_FieldInfo field; GF_Err e; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &i); GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", NULL); gf_node_get_field(com->node, inf->fieldIndex, &field); field.fieldType = inf->fieldType; count = gf_list_count(com->command_fields); maxPos = 0; for (i=0; i<count; i++) { inf = (GF_CommandField *)gf_list_get(com->command_fields, i); if (maxPos < (u32) inf->pos) maxPos = inf->pos; } nbBitsPos = gf_get_bit_size(maxPos); GF_BIFS_WRITE_INT(codec, bs, nbBitsPos, 5, "nbBitsPos", NULL); nbBits = gf_get_bit_size(count); GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, count, nbBits, "count", NULL); for (i=0; i<count; i++) { inf = (GF_CommandField *)gf_list_get(com->command_fields, i); GF_BIFS_WRITE_INT(codec, bs, inf->pos, nbBitsPos, "idx", NULL); field.far_ptr = inf->field_ptr; e = gf_bifs_enc_field(codec, bs, com->node, &field); if (e) return e; } return GF_OK; }
GF_Err BM_ParseRouteReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { GF_Err e; GF_Command *com; u32 RouteID, numBits, ind, node_id, fromID, toID; GF_Route *r; GF_Node *OutNode, *InNode; RouteID = 1+gf_bs_read_int(bs, codec->info->config.RouteIDBits); r = gf_sg_route_find(codec->current_graph, RouteID); /*origin*/ node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); OutNode = gf_sg_find_node(codec->current_graph, node_id); if (!OutNode) return GF_NON_COMPLIANT_BITSTREAM; numBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(OutNode, GF_SG_FIELD_CODING_OUT) - 1); ind = gf_bs_read_int(bs, numBits); e = gf_bifs_get_field_index(OutNode, ind, GF_SG_FIELD_CODING_OUT, &fromID); if (e) return e; /*target*/ node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); InNode = gf_sg_find_node(codec->current_graph, node_id); if (!InNode) return GF_NON_COMPLIANT_BITSTREAM; numBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(InNode, GF_SG_FIELD_CODING_IN) - 1); ind = gf_bs_read_int(bs, numBits); e = gf_bifs_get_field_index(InNode, ind, GF_SG_FIELD_CODING_IN, &toID); if (e) return e; com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_REPLACE); com->RouteID = RouteID; com->fromNodeID = gf_node_get_id(OutNode); com->fromFieldIndex = fromID; com->toNodeID = gf_node_get_id(InNode); com->toFieldIndex = toID; gf_list_add(com_list, com); return codec->LastError; }
GF_Err gf_bifs_dec_node_mask(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, Bool is_proto) { u32 i, numFields, numProtoFields, index, flag, nbBits; GF_Err e; GF_FieldInfo field; //proto coding if (codec->pCurrentProto) { numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL); numProtoFields = gf_sg_proto_get_field_count(codec->pCurrentProto); nbBits = gf_get_bit_size(numProtoFields-1); for (i=0; i<numFields; i++) { flag = gf_bs_read_int(bs, 1); if (!flag) continue; flag = gf_bs_read_int(bs, 1); //IS'ed field, create route for binding to Proto declaration if (flag) { //reference index of our IS'ed proto field flag = gf_bs_read_int(bs, nbBits); e = gf_node_get_field(node, i, &field); if (e) return e; e = BD_SetProtoISed(codec, flag, node, i); } //regular field, parse it (nb: no contextual coding for protos in maskNode, //all node fields are coded else { e = gf_node_get_field(node, i, &field); if (e) return e; e = gf_bifs_dec_field(codec, bs, node, &field, 0); } if (e) return e; } } //regular coding else { 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) return e; e = gf_bifs_dec_field(codec, bs, node, &field, 0); if (e) return e; if (is_proto) gf_sg_proto_mark_field_loaded(node, &field); } } return GF_OK; }
static GF_Err BM_ParseMultipleIndexedReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { u32 ID, ind, field_ind, NumBits, lenpos, lennum, count; GF_Node *node; GF_Err e; GF_Command *com; GF_CommandField *inf; GF_FieldInfo field; ID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); node = gf_sg_find_node(codec->current_graph, ID); if (!node) return GF_NON_COMPLIANT_BITSTREAM; NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1); ind = gf_bs_read_int(bs, NumBits); e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind); if (e) return e; e = gf_node_get_field(node, field_ind, &field); if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; lenpos = gf_bs_read_int(bs, 5); lennum = gf_bs_read_int(bs, 5); count = gf_bs_read_int(bs, lennum); com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_INDEXED_REPLACE); BM_SetCommandNode(com, node); field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); while (count) { inf = gf_sg_command_field_new(com); inf->pos = gf_bs_read_int(bs, lenpos); inf->fieldIndex = field.fieldIndex; inf->fieldType = field.fieldType; if (field.fieldType==GF_SG_VRML_SFNODE) { inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype); if (codec->LastError) goto err; inf->field_ptr = &inf->new_node; gf_node_register(inf->new_node, NULL); } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); e = gf_bifs_dec_sf_field(codec, bs, node, &field, 1); if (e) goto err; } count--; } err: if (e) gf_sg_command_del(com); else gf_list_add(com_list, com); return e; }
GF_Err BE_SceneReplaceEx(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs, GF_List *routes) { u32 i, nbR, nbBits; GF_Err e; /*reserved*/ GF_BIFS_WRITE_INT(codec, bs, 0, 6, "reserved", NULL); GF_BIFS_WRITE_INT(codec, bs, codec->UseName ? 1 : 0, 1, "useName", NULL); if (gf_list_count(com->new_proto_list)) { e = BE_EncProtoList(codec, com->new_proto_list, bs); if (e) goto exit; } else { e = BE_EncProtoList(codec, com->in_scene->protos, bs); if (e) goto exit; } /*NULL root is valid for ProtoLibraries*/ e = gf_bifs_enc_node(codec, com->node, NDT_SFTopNode, bs); if (e || !gf_list_count(routes) ) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasRoute", NULL); return codec->LastError = e; } GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasRoute", NULL); nbR = gf_list_count(routes); nbBits = gf_get_bit_size(nbR); if (nbBits + 5 > nbR) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); /*list*/ for (i=0; i<nbR; i++) { e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(routes, i), bs); if (e) goto exit; GF_BIFS_WRITE_INT(codec, bs, (i+1==nbR) ? 0 : 1, 1, "moreRoute", NULL); } } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL); GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, nbR, nbBits, "nbRoutes", NULL); for (i=0; i<nbR; i++) { e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(routes, i), bs); if (e) goto exit; } } exit: return codec->LastError = e; }
GF_Err BM_ParseIndexDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { u32 NodeID, NumBits, ind, field_ind; s32 pos; GF_Command *com; u8 type; GF_Node *node; GF_Err e; GF_CommandField *inf; GF_FieldInfo field; 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; NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN) - 1); ind = gf_bs_read_int(bs, NumBits); type = gf_bs_read_int(bs, 2); switch (type) { case 0: pos = (u32) 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_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind); if (e) return e; e = gf_node_get_field(node, field_ind, &field); if (e) return e; if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_DELETE); BM_SetCommandNode(com, node); inf = gf_sg_command_field_new(com); inf->pos = pos; inf->fieldIndex = field.fieldIndex; inf->fieldType = gf_sg_vrml_get_sf_type(field.fieldType); gf_list_add(com_list, com); return codec->LastError; }
static GF_Err BE_MultipleReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { u32 i, j, nbBits, count, numFields, allField; Bool use_list; GF_FieldInfo field; GF_Err e; gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); count = gf_list_count(com->command_fields); use_list = 1; numFields = gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_DEF); nbBits = gf_get_bit_size(numFields - 1); if (count < 1+count*(1+nbBits)) use_list = 0; GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL); for (i=0; i<numFields; i++) { GF_CommandField *inf = NULL; gf_bifs_get_field_index(com->node, i, GF_SG_FIELD_CODING_DEF, &allField); for (j=0; j<count; j++) { inf = (GF_CommandField *)gf_list_get(com->command_fields, j); if (inf->fieldIndex==allField) break; inf = NULL; } if (!inf) { if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL); continue; } /*common case*/ gf_node_get_field(com->node, inf->fieldIndex, &field); if (use_list) { /*not end flag*/ GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { /*mask flag*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } if (use_list) GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", (char*)field.name); field.far_ptr = inf->field_ptr; e = gf_bifs_enc_field(codec, bs, com->node, &field); if (e) return e; } /*end flag*/ if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); return GF_OK; }
GF_Err BE_SceneReplace(GF_BifsEncoder *codec, GF_SceneGraph *graph, GF_BitStream *bs) { u32 i, nbR, nbBits; GF_Err e; /*reserved*/ GF_BIFS_WRITE_INT(codec, bs, 0, 6, "reserved", NULL); GF_BIFS_WRITE_INT(codec, bs, codec->UseName ? 1 : 0, 1, "useName", NULL); /*assign current graph*/ codec->scene_graph = graph; e = BE_EncProtoList(codec, codec->scene_graph ? codec->scene_graph->protos : NULL, bs); if (e) goto exit; /*NULL root is valid for ProtoLibraries*/ e = gf_bifs_enc_node(codec, graph ? graph->RootNode : NULL, NDT_SFTopNode, bs); if (e || !graph || !gf_list_count(graph->Routes) ) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasRoute", NULL); return codec->LastError = e; } GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasRoute", NULL); nbR = gf_list_count(graph->Routes); nbBits = gf_get_bit_size(nbR); if (nbBits + 5 > nbR) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); /*list*/ for (i=0; i<nbR; i++) { e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(graph->Routes, i), bs); if (e) goto exit; GF_BIFS_WRITE_INT(codec, bs, (i+1==nbR) ? 0 : 1, 1, "moreRoute", NULL); } } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL); GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, nbR, nbBits, "nbRoutes", NULL); for (i=0; i<nbR; i++) { e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(graph->Routes, i), bs); if (e) goto exit; } } exit: return codec->LastError = e; }
static GF_Err BE_EncProtoDelete(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { u32 nbBits, i; Bool use_list = 0; nbBits = gf_get_bit_size(com->del_proto_list_size); if (nbBits+5>com->del_proto_list_size) use_list = 1; GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL); if (!use_list) { GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "len", NULL); GF_BIFS_WRITE_INT(codec, bs, com->del_proto_list_size, nbBits, "len", NULL); } for (i=0; i<com->del_proto_list_size; i++) { if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreProto", NULL); GF_BIFS_WRITE_INT(codec, bs, com->del_proto_list[i], codec->info->config.ProtoIDBits, "protoID", NULL); } if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL); return GF_OK; }
GF_Err BE_IndexInsert(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) { GF_Err e; u32 NumBits, ind; GF_FieldInfo field, sffield; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); /*index insertion uses IN mode for field index*/ NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); switch (inf->pos) { case 0: GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idx"); break; case -1: GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx"); break; default: GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx"); GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL); break; } 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; memcpy(&sffield, &field, sizeof(GF_FieldInfo)); sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); sffield.far_ptr = inf->field_ptr; /*rescale the MFField and parse the SFField*/ if (field.fieldType==GF_SG_VRML_MFNODE) { return gf_bifs_enc_node(codec, inf->new_node, field.NDTtype, bs); } else { return gf_bifs_enc_sf_field(codec, bs, com->node, &sffield); } }
void SFE_PutInteger(ScriptEnc *sc_enc, char *str) { u32 nbBits, val = 0; if (sc_enc->emul) return; if ((str[0]=='0') && (str[1]=='x' || str[1]=='X')) { val = strtoul(sc_enc->token, (char **) NULL, 16); } else if (str[0]=='0' && isdigit(str[1])) { val = strtoul(str, (char **) NULL, 8); } else if (isdigit(str[0])) { val = strtoul(str, (char **) NULL, 10); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: %s is not an integer\n", str)); sc_enc->err = GF_BAD_PARAM; return; } nbBits = gf_get_bit_size(val); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbBits, 5, "nbBitsInteger", NULL); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, val, nbBits, "value", sc_enc->token); }
void SFS_Identifier(ScriptParser *parser) { u32 index; char name[500]; if (parser->codec->LastError) return; //received if (gf_bs_read_int(parser->bs, 1)) { index = gf_bs_read_int(parser->bs, gf_get_bit_size(gf_list_count(parser->identifiers) - 1)); SFS_AddString(parser, (char *)gf_list_get(parser->identifiers, index)); } //parse else{ gf_bifs_dec_name(parser->bs, name); gf_list_add(parser->identifiers, gf_strdup(name)); SFS_AddString(parser, name); } }
GF_Err ParseScriptField(ScriptParser *parser) { GF_ScriptField *field; GF_Err e; u32 eventType, fieldType; char name[1000]; GF_FieldInfo info; eventType = gf_bs_read_int(parser->bs, 2); fieldType = gf_bs_read_int(parser->bs, 6); gf_bifs_dec_name(parser->bs, name); field = gf_sg_script_field_new(parser->script, eventType, fieldType, name); if (!field) return GF_NON_COMPLIANT_BITSTREAM; //save the name in the list of identifiers gf_list_add(parser->identifiers, gf_strdup(name)); if (parser->codec->pCurrentProto) { Bool isISfield = gf_bs_read_int(parser->bs, 1); if (isISfield) { u32 numProtoField = gf_sg_proto_get_field_count(parser->codec->pCurrentProto); u32 numBits = gf_get_bit_size(numProtoField - 1); u32 field_all = gf_bs_read_int(parser->bs, numBits); e = gf_sg_script_field_get_info(field, &info); if (e) return e; e = gf_sg_proto_field_set_ised(parser->codec->pCurrentProto, field_all, parser->script, info.fieldIndex); return e; } } /*get default value*/ if (eventType == GF_SG_SCRIPT_TYPE_FIELD) { if (gf_bs_read_int(parser->bs, 1)) { e = gf_sg_script_field_get_info(field, &info); if (e) return e; gf_bifs_dec_field(parser->codec, parser->bs, parser->script, &info); } } return parser->codec->LastError; }
GF_Err BM_ParseFieldReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { GF_Err e; GF_Command *com; u32 NodeID, ind, field_ind, NumBits; GF_Node *node; GF_FieldInfo field; 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; NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1); ind = gf_bs_read_int(bs, NumBits); e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind); if (e) return e; e = gf_node_get_field(node, field_ind, &field); com = gf_sg_command_new(codec->current_graph, GF_SG_FIELD_REPLACE); BM_SetCommandNode(com, node); inf = gf_sg_command_field_new(com); inf->fieldIndex = field_ind; inf->fieldType = field.fieldType; 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(field.fieldType); } /*parse the field*/ codec->LastError = gf_bifs_dec_field(codec, bs, node, &field, 1); gf_list_add(com_list, com); return codec->LastError; }
static void DEV_Start(struct __input_device *ifce) { GF_BitStream *bs; char *buf, *szWord; u32 len, val, i, buf_size; szWord = "Hello InputSensor!"; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*HTK sensor buffer format: SFString - SFInt32 - SFFloat*/ gf_bs_write_int(bs, 1, 1); len = strlen(szWord); val = gf_get_bit_size(len); gf_bs_write_int(bs, val, 5); gf_bs_write_int(bs, len, val); for (i=0; i<len; i++) gf_bs_write_int(bs, szWord[i], 8); gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); ifce->DispatchFrame(ifce, buf, buf_size); gf_free(buf); }
GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com) { GF_Err e; GF_Node *new_node; u32 size, length, w, h, i; char *buffer; //blindly call unquantize. return is OK, error or GF_EOS if (codec->ActiveQP && node) { e = gf_bifs_dec_unquant_field(codec, bs, node, field); if (e != GF_EOS) return e; } //not quantized, use normal scheme switch (field->fieldType) { case GF_SG_VRML_SFBOOL: * ((SFBool *) field->far_ptr) = (SFBool) gf_bs_read_int(bs, 1); break; case GF_SG_VRML_SFCOLOR: ((SFColor *)field->far_ptr)->red = BD_ReadSFFloat(codec, bs);; ((SFColor *)field->far_ptr)->green = BD_ReadSFFloat(codec, bs); ((SFColor *)field->far_ptr)->blue = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFFLOAT: *((SFFloat *)field->far_ptr) = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFINT32: *((SFInt32 *)field->far_ptr) = (s32) gf_bs_read_int(bs, 32); break; case GF_SG_VRML_SFTIME: *((SFTime *)field->far_ptr) = gf_bs_read_double(bs); if (node) BD_CheckSFTimeOffset(codec, node, field); break; case GF_SG_VRML_SFVEC2F: ((SFVec2f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs); ((SFVec2f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFVEC3F: ((SFVec3f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs); ((SFVec3f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs); ((SFVec3f *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFROTATION: ((SFRotation *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs); ((SFRotation *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs); ((SFRotation *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs); ((SFRotation *)field->far_ptr)->q = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFSTRING: size = gf_bs_read_int(bs, 5); length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) { M_CacheTexture *ct = (M_CacheTexture *) node; ct->data_len = length; if (ct->data) gf_free(ct->data); ct->data = gf_malloc(sizeof(char)*length); gf_bs_read_data(bs, (char*)ct->data, length); } else if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) { M_BitWrapper *bw = (M_BitWrapper*) node; if (bw->buffer.buffer) gf_free(bw->buffer.buffer); bw->buffer_len = length; bw->buffer.buffer = gf_malloc(sizeof(char)*length); gf_bs_read_data(bs, (char*)bw->buffer.buffer, length); } else { if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer); ((SFString *)field->far_ptr)->buffer = (char *)gf_malloc(sizeof(char)*(length+1)); memset(((SFString *)field->far_ptr)->buffer , 0, length+1); for (i=0; i<length; i++) { ((SFString *)field->far_ptr)->buffer[i] = gf_bs_read_int(bs, 8); } } break; case GF_SG_VRML_SFURL: { SFURL *url = (SFURL *) field->far_ptr; size = gf_bs_read_int(bs, 1); if (size) { if (url->url) gf_free(url->url ); url->url = NULL; length = gf_bs_read_int(bs, 10); url->OD_ID = length; } else { if ( url->OD_ID ) url->OD_ID = (u32) -1; size = gf_bs_read_int(bs, 5); length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; buffer = NULL; if (length) { buffer = (char *)gf_malloc(sizeof(char)*(length+1)); memset(buffer, 0, length+1); for (i=0; i<length; i++) buffer[i] = gf_bs_read_int(bs, 8); } if (url->url) gf_free( url->url); /*if URL is empty set it to NULL*/ if (buffer && strlen(buffer)) { url->url = buffer; } else { gf_free(buffer); url->url = NULL; } } } break; case GF_SG_VRML_SFIMAGE: if (((SFImage *)field->far_ptr)->pixels) gf_free(((SFImage *)field->far_ptr)->pixels); w = gf_bs_read_int(bs, 12); h = gf_bs_read_int(bs, 12); length = gf_bs_read_int(bs, 2); if (length > 3) length = 3; length += 1; size = w * h * length; if (gf_bs_available(bs) < size) return GF_NON_COMPLIANT_BITSTREAM; ((SFImage *)field->far_ptr)->width = w; ((SFImage *)field->far_ptr)->height = h; ((SFImage *)field->far_ptr)->numComponents = length; ((SFImage *)field->far_ptr)->pixels = (unsigned char *)gf_malloc(sizeof(char)*size); //WARNING: Buffers are NOT ALIGNED IN THE BITSTREAM for (i=0; i<size; i++) { ((SFImage *)field->far_ptr)->pixels[i] = gf_bs_read_int(bs, 8); } break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *sfcb = (SFCommandBuffer *)field->far_ptr; if (sfcb->buffer) { gf_free(sfcb->buffer); sfcb->buffer = NULL; } while (gf_list_count(sfcb->commandList)) { GF_Command *com = (GF_Command*)gf_list_get(sfcb->commandList, 0); gf_list_rem(sfcb->commandList, 0); gf_sg_command_del(com); } size = gf_bs_read_int(bs, 5); length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; sfcb->bufferSize = length; if (length) { sfcb->buffer = (unsigned char *)gf_malloc(sizeof(char)*(length)); //WARNING Buffers are NOT ALIGNED IN THE BITSTREAM for (i=0; i<length; i++) { sfcb->buffer[i] = gf_bs_read_int(bs, 8); } } //notify the node - this is needed in case an enhencement layer replaces the buffer, in which case //the # ID Bits may change SFCommandBufferChanged(codec, node); /* 1 - memory mode, register command buffer for later parsing 2 - InputSensor only works on decompressed commands */ if (codec->dec_memory_mode || (node->sgprivate->tag==TAG_MPEG4_InputSensor)) { CommandBufferItem *cbi = (CommandBufferItem *)gf_malloc(sizeof(CommandBufferItem)); cbi->node = node; cbi->cb = sfcb; gf_list_add(codec->command_buffers, cbi); } } break; case GF_SG_VRML_SFNODE: //for nodes the field ptr is a ptr to the field, which is a node ptr ;) new_node = gf_bifs_dec_node(codec, bs, field->NDTtype); if (new_node) { e = gf_node_register(new_node, is_mem_com ? NULL : node); if (e) return e; } //it may happen that new_node is NULL (this is valid for a proto declaration) *((GF_Node **) field->far_ptr) = new_node; break; case GF_SG_VRML_SFSCRIPT: #ifdef GPAC_HAS_SPIDERMONKEY codec->LastError = SFScript_Parse(codec, (SFScript*)field->far_ptr, bs, node); #else return GF_NOT_SUPPORTED; #endif break; case GF_SG_VRML_SFATTRREF: { SFAttrRef *ar = (SFAttrRef *)field->far_ptr; u32 nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); ar->node = gf_sg_find_node(codec->current_graph, nodeID); if (!ar->node) { } else { u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1); u32 field_ref = gf_bs_read_int(bs, nbBitsDEF); codec->LastError = gf_bifs_get_field_index(ar->node, field_ref, GF_SG_FIELD_CODING_DEF, &ar->fieldIndex); } } break; default: return GF_NON_COMPLIANT_BITSTREAM; } return codec->LastError; }
static GF_Err gf_sm_setup_bifsenc(GF_SceneEngine *seng, GF_StreamContext *sc, GF_ESD *esd) { char *data; u32 data_len; u32 nbb; Bool encode_names, delete_bcfg; GF_BIFSConfig *bcfg; if (!esd->decoderConfig || (esd->decoderConfig->streamType != GF_STREAM_SCENE)) return GF_BAD_PARAM; if (!seng->bifsenc) seng->bifsenc = gf_bifs_encoder_new(seng->ctx->scene_graph); delete_bcfg = 0; /*inputctx is not properly setup, do it*/ if (!esd->decoderConfig->decoderSpecificInfo) { bcfg = (GF_BIFSConfig*)gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG); bcfg->pixelMetrics = seng->ctx->is_pixel_metrics; bcfg->pixelWidth = seng->ctx->scene_width; bcfg->pixelHeight = seng->ctx->scene_height; delete_bcfg = 1; } /*regular case*/ else if (esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_BIFS_CFG_TAG) { bcfg = (GF_BIFSConfig *)esd->decoderConfig->decoderSpecificInfo; } /*happens when loading from MP4 in which case BIFSc is not decoded*/ else { bcfg = gf_odf_get_bifs_config(esd->decoderConfig->decoderSpecificInfo, esd->decoderConfig->objectTypeIndication); delete_bcfg = 1; } /*NO CHANGE TO BIFSC otherwise the generated update will not match the input context The only case we modify the bifs config is when XXXBits is not specified*/ nbb = gf_get_bit_size(seng->ctx->max_node_id); if (!bcfg->nodeIDbits) bcfg->nodeIDbits = nbb; else if (bcfg->nodeIDbits<nbb) { GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.NodeIDBits too small (%d bits vs %d nodes)\n", bcfg->nodeIDbits, seng->ctx->max_node_id)); } nbb = gf_get_bit_size(seng->ctx->max_route_id); if (!bcfg->routeIDbits) bcfg->routeIDbits = nbb; else if (bcfg->routeIDbits<nbb) { GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.RouteIDBits too small (%d bits vs %d routes)\n", bcfg->routeIDbits, seng->ctx->max_route_id)); } nbb = gf_get_bit_size(seng->ctx->max_proto_id); if (!bcfg->protoIDbits) bcfg->protoIDbits=nbb; else if (bcfg->protoIDbits<nbb) { GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.ProtoIDBits too small (%d bits vs %d protos)\n", bcfg->protoIDbits, seng->ctx->max_proto_id)); } /*this is the real pb, not stored in cfg or file level, set at EACH replaceScene*/ encode_names = 0; /* The BIFS Config that is passed here should be the BIFSConfig from the IOD */ gf_bifs_encoder_new_stream(seng->bifsenc, esd->ESID, bcfg, encode_names, 0); if (delete_bcfg) gf_odf_desc_del((GF_Descriptor *)bcfg); gf_bifs_encoder_get_config(seng->bifsenc, esd->ESID, &data, &data_len); if (esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo); esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); esd->decoderConfig->decoderSpecificInfo->data = data; esd->decoderConfig->decoderSpecificInfo->dataLength = data_len; sc->dec_cfg = gf_malloc(sizeof(char)*data_len); memcpy(sc->dec_cfg, data, data_len); sc->dec_cfg_len = data_len; esd->decoderConfig->objectTypeIndication = gf_bifs_encoder_get_version(seng->bifsenc, esd->ESID); return GF_OK; }
GF_Err gf_bifs_enc_mf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field) { GF_ChildNodeItem *list = NULL; GF_Err e; u32 nbBits, qp_local; Bool use_list, qp_on, initial_qp; u32 nbF, i; GF_FieldInfo sffield; nbF = 0; if (field->fieldType != GF_SG_VRML_MFNODE) { nbF = field->far_ptr ? ((GenMFField *)field->far_ptr)->count : 0; if (!nbF && (field->fieldType == GF_SG_VRML_MFSCRIPT)) nbF = 1; } else if (field->far_ptr) { list = *((GF_ChildNodeItem **)field->far_ptr); nbF = gf_node_list_get_count(list); } /*reserved*/ GF_BIFS_WRITE_INT(codec, bs, 0, 1, "reserved", NULL); if (!nbF) { /*is list*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); /*end flag*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); return GF_OK; } /*do we work in list or vector*/ use_list = GF_FALSE; nbBits = gf_get_bit_size(nbF); if (nbBits + 5 > nbF + 1) use_list = GF_TRUE; GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL); if (!use_list) { GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, nbF, nbBits, "length", NULL); } memset(&sffield, 0, sizeof(GF_FieldInfo)); sffield.fieldIndex = field->fieldIndex; sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType); sffield.NDTtype = field->NDTtype; initial_qp = qp_on = GF_FALSE; qp_local = 0; initial_qp = codec->ActiveQP ? GF_TRUE : GF_FALSE; for (i=0; i<nbF; i++) { if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); if (field->fieldType != GF_SG_VRML_MFNODE) { gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, &sffield.far_ptr, i); e = gf_bifs_enc_sf_field(codec, bs, node, &sffield); } else { assert(list); e = gf_bifs_enc_node(codec, list->node, field->NDTtype, bs, node); /*activate QP*/ if (list->node->sgprivate->tag == TAG_MPEG4_QuantizationParameter) { qp_local = ((M_QuantizationParameter *)list->node)->isLocal; if (qp_on) gf_bifs_enc_qp_remove(codec, GF_FALSE); e = gf_bifs_enc_qp_set(codec, list->node); if (e) return e; qp_on = GF_TRUE; if (qp_local) qp_local = 2; } list = list->next; } if (e) return e; if (qp_on && qp_local) { if (qp_local == 2) qp_local -= 1; else { gf_bifs_enc_qp_remove(codec, initial_qp); qp_local = qp_on = GF_FALSE; } } } if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); if (qp_on) gf_bifs_enc_qp_remove(codec, initial_qp); /*for QP14*/ gf_bifs_enc_qp14_set_length(codec, nbF); return GF_OK; }
GF_Err EncNodeFields(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node) { u8 mode; GF_Route *isedField; GF_Node *clone; GF_Err e; s32 *enc_fields; u32 numBitsALL, numBitsDEF, allInd, count, i, nbBitsProto, nbFinal; Bool use_list, nodeIsFDP = GF_FALSE; GF_FieldInfo field, clone_field; e = GF_OK; if (codec->encoding_proto) { mode = GF_SG_FIELD_CODING_ALL; nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(codec->encoding_proto) - 1); numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL) - 1); } else { mode = GF_SG_FIELD_CODING_DEF; nbBitsProto = 0; numBitsALL = 0; } count = gf_node_get_num_fields_in_mode(node, mode); if (node->sgprivate->tag==TAG_MPEG4_Script) count = 3; if (!count) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isMask", NULL); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); return GF_OK; } if (node->sgprivate->tag == TAG_ProtoNode) { clone = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);; } else { clone = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag); } if (clone) gf_node_register(clone, NULL); numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF) - 1); enc_fields = (s32*)gf_malloc(sizeof(s32) * count); nbFinal = 0; for (i=0; i<count; i++) { enc_fields[i] = -1; /*get field in ALL mode*/ if (mode == GF_SG_FIELD_CODING_ALL) { allInd = i; } else { gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &allInd); } /*encode proto code*/ if (codec->encoding_proto) { isedField = gf_bifs_enc_is_field_ised(codec, node, allInd); if (isedField) { enc_fields[i] = allInd; nbFinal ++; continue; } } /*common case*/ gf_node_get_field(node, allInd, &field); /*if event don't encode (happens when encoding protos)*/ if ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) continue; /*if field is default skip*/ switch (field.fieldType) { case GF_SG_VRML_SFNODE: if (* (GF_Node **) field.far_ptr) { enc_fields[i] = allInd; nbFinal++; } break; case GF_SG_VRML_MFNODE: if (* (GF_ChildNodeItem **) field.far_ptr) { enc_fields[i] = allInd; nbFinal++; } break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr; if (gf_list_count(cb->commandList)) { enc_fields[i] = allInd; nbFinal++; } } break; case GF_SG_VRML_MFSCRIPT: enc_fields[i] = allInd; nbFinal++; break; default: gf_node_get_field(clone, allInd, &clone_field); if (!gf_sg_vrml_field_equal(clone_field.far_ptr, field.far_ptr, field.fieldType)) { enc_fields[i] = allInd; nbFinal++; } break; } } if (clone) gf_node_unregister(clone, NULL); use_list = GF_TRUE; /* patch for FDP node : */ /* cannot use default field sorting due to spec "mistake", so use list to imply inversion between field 2 and field 3 of FDP*/ if (node->sgprivate->tag == TAG_MPEG4_FDP) { s32 s4SwapValue = enc_fields[2]; enc_fields[2] = enc_fields[3]; enc_fields[3] = s4SwapValue; nodeIsFDP = GF_TRUE; use_list = GF_TRUE; } /*number of bits in mask node is count*1, in list node is 1+nbFinal*(1+numBitsDEF) */ else if (count < 1+nbFinal*(1+numBitsDEF)) use_list = GF_FALSE; GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL); for (i=0; i<count; i++) { if (enc_fields[i] == -1) { if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL); continue; } allInd = (u32) enc_fields[i]; /*encode proto code*/ if (codec->encoding_proto) { isedField = gf_bifs_enc_is_field_ised(codec, node, allInd); if (isedField) { if (use_list) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isedField", NULL); if (use_list) GF_BIFS_WRITE_INT(codec, bs, allInd, numBitsALL, "nodeField", NULL); if (isedField->ToNode == node) { GF_BIFS_WRITE_INT(codec, bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL); } continue; } } /*common case*/ gf_node_get_field(node, allInd, &field); if (use_list) { /*not end flag*/ GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { /*mask flag*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } /*not ISed field*/ if (codec->encoding_proto) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isedField", NULL); if (use_list) { if (codec->encoding_proto || nodeIsFDP) { u32 ind=0; /*for proto, we're in ALL mode and we need DEF mode*/ /*for FDP, encoding requires to get def id from all id as fields 2 and 3 are reversed*/ gf_bifs_field_index_by_mode(node, allInd, GF_SG_FIELD_CODING_DEF, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, numBitsDEF, "field", (char*)field.name); } else { GF_BIFS_WRITE_INT(codec, bs, i, numBitsDEF, "field", (char*)field.name); } } e = gf_bifs_enc_field(codec, bs, node, &field); if (e) goto exit; } /*end flag*/ if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); exit: gf_free(enc_fields); return e; }
GF_Err gf_bifs_enc_sf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field) { GF_Err e; if (node) { e = gf_bifs_enc_quant_field(codec, bs, node, field); if (e != GF_EOS) return e; } switch (field->fieldType) { case GF_SG_VRML_SFBOOL: GF_BIFS_WRITE_INT(codec, bs, * ((SFBool *)field->far_ptr), 1, "SFBool", NULL); break; case GF_SG_VRML_SFCOLOR: BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->red, bs, "color.red"); BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->green, bs, "color.green"); BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->blue, bs, "color.blue"); break; case GF_SG_VRML_SFFLOAT: BE_WriteSFFloat(codec, * ((SFFloat *)field->far_ptr), bs, NULL); break; case GF_SG_VRML_SFINT32: GF_BIFS_WRITE_INT(codec, bs, * ((SFInt32 *)field->far_ptr), 32, "SFInt32", NULL); break; case GF_SG_VRML_SFROTATION: BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->x, bs, "rot.x"); BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->y, bs, "rot.y"); BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->z, bs, "rot.z"); BE_WriteSFFloat(codec, ((SFRotation *)field->far_ptr)->q, bs, "rot.theta"); break; case GF_SG_VRML_SFSTRING: if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) { u32 size, val; char buf[4096]; char *res_src = NULL; const char *src = ((SFString*)field->far_ptr)->buffer; FILE *f; if (codec->src_url) res_src = gf_url_concatenate(codec->src_url, src); f = gf_fopen(res_src ? res_src : src, "rb"); if (!f) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot open source file %s for encoding CacheTexture\n", res_src ? res_src : src)); return GF_URL_ERROR; } if (res_src) gf_free(res_src); gf_fseek(f, 0, SEEK_END); size = (u32) gf_ftell(f); val = gf_get_bit_size(size); GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, size, val, "length", NULL); gf_fseek(f, 0, SEEK_SET); while (size) { u32 read = (u32) fread(buf, 1, 4096, f); gf_bs_write_data(bs, buf, read); size -= read; } } else { u32 i, val, len; char *str = (char *) ((SFString*)field->far_ptr)->buffer; if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) { len = ((M_BitWrapper*)node)->buffer_len; } else { len = str ? (u32) strlen(str) : 0; } val = gf_get_bit_size(len); GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL); for (i=0; i<len; i++) gf_bs_write_int(bs, str[i], 8); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\n", 8*len, str) ); } break; case GF_SG_VRML_SFTIME: gf_bs_write_double(bs, *((SFTime *)field->far_ptr)); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] SFTime\t\t%d\t\t%g\n", 64, *((SFTime *)field->far_ptr))); break; case GF_SG_VRML_SFVEC2F: BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->x, bs, "vec2f.x"); BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->y, bs, "vec2f.y"); break; case GF_SG_VRML_SFVEC3F: BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->x, bs, "vec3f.x"); BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->y, bs, "vec3f.y"); BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->z, bs, "vec3f.z"); break; case GF_SG_VRML_SFURL: { SFURL *url = (SFURL *) field->far_ptr; GF_BIFS_WRITE_INT(codec, bs, (url->OD_ID>0) ? 1 : 0, 1, "hasODID", "SFURL"); if (url->OD_ID>0) { GF_BIFS_WRITE_INT(codec, bs, url->OD_ID, 10, "ODID", "SFURL"); } else { u32 i, len = url->url ? (u32) strlen(url->url) : 0; u32 val = gf_get_bit_size(len); GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL); for (i=0; i<len; i++) gf_bs_write_int(bs, url->url[i], 8); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\t\t//SFURL\n", 8*len, url->url)); } } break; case GF_SG_VRML_SFIMAGE: { u32 size, i; SFImage *img = (SFImage *)field->far_ptr; GF_BIFS_WRITE_INT(codec, bs, img->width, 12, "width", "SFImage"); GF_BIFS_WRITE_INT(codec, bs, img->height, 12, "height", "SFImage"); GF_BIFS_WRITE_INT(codec, bs, img->numComponents - 1, 2, "nbComp", "SFImage"); size = img->width * img->height * img->numComponents; for (i=0; i<size; i++) gf_bs_write_int(bs, img->pixels[i], 8); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] pixels\t\t%d\t\tnot dumped\t\t//SFImage\n", 8*size)); } break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *cb = (SFCommandBuffer *) field->far_ptr; if (cb->buffer) gf_free(cb->buffer); cb->buffer = NULL; cb->bufferSize = 0; if (gf_list_count(cb->commandList)) { u32 i, nbBits; GF_BitStream *bs_cond = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*SFCommandBuffer*/\n" )); e = gf_bifs_enc_commands(codec, cb->commandList, bs_cond); if (!e) gf_bs_get_content(bs_cond, (char**)&cb->buffer, &cb->bufferSize); gf_bs_del(bs_cond); if (e) return e; GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*End SFCommandBuffer*/\n")); nbBits = gf_get_bit_size(cb->bufferSize); GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "NbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, cb->bufferSize, nbBits, "BufferSize", NULL); for (i=0; i<cb->bufferSize; i++) GF_BIFS_WRITE_INT(codec, bs, cb->buffer[i], 8, "buffer byte", NULL); } /*empty command buffer*/ else { GF_BIFS_WRITE_INT(codec, bs, 0, 5, "NbBits", NULL); } } break; case GF_SG_VRML_SFNODE: return gf_bifs_enc_node(codec, *((GF_Node **)field->far_ptr), field->NDTtype, bs, node); case GF_SG_VRML_SFSCRIPT: #ifdef GPAC_HAS_SPIDERMONKEY codec->LastError = SFScript_Encode(codec, (SFScript *)field->far_ptr, bs, node); #else return GF_NOT_SUPPORTED; #endif break; case GF_SG_VRML_SFATTRREF: { u32 idx=0; SFAttrRef *ar = (SFAttrRef *)field->far_ptr; u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(ar->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); gf_bifs_field_index_by_mode(ar->node, ar->fieldIndex, GF_SG_FIELD_CODING_DEF, &idx); GF_BIFS_WRITE_INT(codec, bs, idx, nbBitsDEF, "field", NULL); } break; default: return GF_NOT_SUPPORTED; } return codec->LastError; }
GF_EXPORT GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, u32 Path_MTU, u32 max_ptime, u32 default_rtp_rate, u32 flags, u8 PayloadID, Bool copy_media, u32 InterleaveGroupID, u8 InterleaveGroupPriority, GF_Err *e) { GF_SLConfig my_sl; u32 descIndex, MinSize, MaxSize, avgTS, streamType, oti, const_dur, nb_ch, maxDTSDelta; u8 OfficialPayloadID; u32 TrackMediaSubType, TrackMediaType, hintType, nbEdts, required_rate, force_dts_delta, avc_nalu_size, PL_ID, bandwidth, IV_length, KI_length; const char *url, *urn; char *mpeg4mode; Bool is_crypted, has_mpeg4_mapping; GF_RTPHinter *tmp; GF_ESD *esd; *e = GF_BAD_PARAM; if (!file || !TrackNum || !gf_isom_get_track_id(file, TrackNum)) return NULL; if (!gf_isom_get_sample_count(file, TrackNum)) { *e = GF_OK; return NULL; } *e = GF_NOT_SUPPORTED; nbEdts = gf_isom_get_edit_segment_count(file, TrackNum); if (nbEdts>1) { u64 et, sd, mt; u8 em; gf_isom_get_edit_segment(file, TrackNum, 1, &et, &sd, &mt, &em); if ((nbEdts>2) || (em!=GF_ISOM_EDIT_EMPTY)) { GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[rtp hinter] Cannot hint track whith EditList\n")); return NULL; } } if (nbEdts) gf_isom_remove_edit_segments(file, TrackNum); if (!gf_isom_is_track_enabled(file, TrackNum)) return NULL; /*by default NO PL signaled*/ PL_ID = 0; OfficialPayloadID = 0; force_dts_delta = 0; streamType = oti = 0; mpeg4mode = NULL; required_rate = 0; is_crypted = 0; IV_length = KI_length = 0; oti = 0; nb_ch = 0; avc_nalu_size = 0; has_mpeg4_mapping = 1; TrackMediaType = gf_isom_get_media_type(file, TrackNum); TrackMediaSubType = gf_isom_get_media_subtype(file, TrackNum, 1); /*for max compatibility with QT*/ if (!default_rtp_rate) default_rtp_rate = 90000; /*timed-text is a bit special, we support multiple stream descriptions & co*/ if ( (TrackMediaType==GF_ISOM_MEDIA_TEXT) || (TrackMediaType==GF_ISOM_MEDIA_SUBT)) { hintType = GF_RTP_PAYT_3GPP_TEXT; oti = GPAC_OTI_TEXT_MPEG4; streamType = GF_STREAM_TEXT; /*fixme - this works cos there's only one PL for text in mpeg4 at the current time*/ PL_ID = 0x10; } else { if (gf_isom_get_sample_description_count(file, TrackNum) > 1) return NULL; TrackMediaSubType = gf_isom_get_media_subtype(file, TrackNum, 1); switch (TrackMediaSubType) { case GF_ISOM_SUBTYPE_MPEG4_CRYP: is_crypted = 1; case GF_ISOM_SUBTYPE_MPEG4: esd = gf_isom_get_esd(file, TrackNum, 1); hintType = GF_RTP_PAYT_MPEG4; if (esd) { streamType = esd->decoderConfig->streamType; oti = esd->decoderConfig->objectTypeIndication; if (esd->URLString) hintType = 0; /*AAC*/ if ((streamType==GF_STREAM_AUDIO) && esd->decoderConfig->decoderSpecificInfo /*(nb: we use mpeg4 for MPEG-2 AAC)*/ && ((oti==GPAC_OTI_AUDIO_AAC_MPEG4) || (oti==GPAC_OTI_AUDIO_AAC_MPEG4) || (oti==GPAC_OTI_AUDIO_AAC_MPEG2_MP) || (oti==GPAC_OTI_AUDIO_AAC_MPEG2_LCP) || (oti==GPAC_OTI_AUDIO_AAC_MPEG2_SSRP)) ) { u32 sample_rate; GF_M4ADecSpecInfo a_cfg; gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg); nb_ch = a_cfg.nb_chan; sample_rate = a_cfg.base_sr; PL_ID = a_cfg.audioPL; switch (a_cfg.base_object_type) { case GF_M4A_AAC_MAIN: case GF_M4A_AAC_LC: if (flags & GP_RTP_PCK_USE_LATM_AAC) { hintType = GF_RTP_PAYT_LATM; break; } case GF_M4A_AAC_SBR: case GF_M4A_AAC_PS: case GF_M4A_AAC_LTP: case GF_M4A_AAC_SCALABLE: case GF_M4A_ER_AAC_LC: case GF_M4A_ER_AAC_LTP: case GF_M4A_ER_AAC_SCALABLE: mpeg4mode = "AAC"; break; case GF_M4A_CELP: case GF_M4A_ER_CELP: mpeg4mode = "CELP"; break; } required_rate = sample_rate; } /*MPEG1/2 audio*/ else if ((streamType==GF_STREAM_AUDIO) && ((oti==GPAC_OTI_AUDIO_MPEG2_PART3) || (oti==GPAC_OTI_AUDIO_MPEG1))) { u32 sample_rate; if (!is_crypted) { GF_ISOSample *samp = gf_isom_get_sample(file, TrackNum, 1, NULL); u32 hdr = GF_4CC((u8)samp->data[0], (u8)samp->data[1], (u8)samp->data[2], (u8)samp->data[3]); nb_ch = gf_mp3_num_channels(hdr); sample_rate = gf_mp3_sampling_rate(hdr); gf_isom_sample_del(&samp); hintType = GF_RTP_PAYT_MPEG12_AUDIO; /*use official RTP/AVP payload type*/ OfficialPayloadID = 14; required_rate = 90000; } /*encrypted MP3 must be sent through MPEG-4 generic to signal all ISMACryp stuff*/ else { u8 bps; gf_isom_get_audio_info(file, TrackNum, 1, &sample_rate, &nb_ch, &bps); required_rate = sample_rate; } } /*QCELP audio*/ else if ((streamType==GF_STREAM_AUDIO) && (oti==GPAC_OTI_AUDIO_13K_VOICE)) { hintType = GF_RTP_PAYT_QCELP; OfficialPayloadID = 12; required_rate = 8000; streamType = GF_STREAM_AUDIO; nb_ch = 1; } /*EVRC/SVM audio*/ else if ((streamType==GF_STREAM_AUDIO) && ((oti==GPAC_OTI_AUDIO_EVRC_VOICE) || (oti==GPAC_OTI_AUDIO_SMV_VOICE)) ) { hintType = GF_RTP_PAYT_EVRC_SMV; required_rate = 8000; streamType = GF_STREAM_AUDIO; nb_ch = 1; } /*visual streams*/ else if (streamType==GF_STREAM_VISUAL) { if (oti==GPAC_OTI_VIDEO_MPEG4_PART2) { GF_M4VDecSpecInfo dsi; gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); PL_ID = dsi.VideoPL; } /*MPEG1/2 video*/ if ( ((oti>=GPAC_OTI_VIDEO_MPEG2_SIMPLE) && (oti<=GPAC_OTI_VIDEO_MPEG2_422)) || (oti==GPAC_OTI_VIDEO_MPEG1)) { if (!is_crypted) { hintType = GF_RTP_PAYT_MPEG12_VIDEO; OfficialPayloadID = 32; } } /*for ISMA*/ if (is_crypted) { /*that's another pain with ISMACryp, even if no B-frames the DTS is signaled...*/ if (oti==GPAC_OTI_VIDEO_MPEG4_PART2) force_dts_delta = 22; else if (oti==GPAC_OTI_VIDEO_AVC) { flags &= ~GP_RTP_PCK_USE_MULTI; force_dts_delta = 22; } flags |= GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_SIGNAL_TS; } required_rate = default_rtp_rate; } /*systems streams*/ else if (gf_isom_has_sync_shadows(file, TrackNum) || gf_isom_has_sample_dependency(file, TrackNum)) { flags |= GP_RTP_PCK_SYSTEMS_CAROUSEL; } gf_odf_desc_del((GF_Descriptor*)esd); } break; case GF_ISOM_SUBTYPE_3GP_H263: hintType = GF_RTP_PAYT_H263; required_rate = 90000; streamType = GF_STREAM_VISUAL; OfficialPayloadID = 34; /*not 100% compliant (short header is missing) but should still work*/ oti = GPAC_OTI_VIDEO_MPEG4_PART2; PL_ID = 0x01; break; case GF_ISOM_SUBTYPE_3GP_AMR: required_rate = 8000; hintType = GF_RTP_PAYT_AMR; streamType = GF_STREAM_AUDIO; has_mpeg4_mapping = 0; nb_ch = 1; break; case GF_ISOM_SUBTYPE_3GP_AMR_WB: required_rate = 16000; hintType = GF_RTP_PAYT_AMR_WB; streamType = GF_STREAM_AUDIO; has_mpeg4_mapping = 0; nb_ch = 1; break; case GF_ISOM_SUBTYPE_AVC_H264: case GF_ISOM_SUBTYPE_AVC2_H264: case GF_ISOM_SUBTYPE_SVC_H264: { GF_AVCConfig *avcc = gf_isom_avc_config_get(file, TrackNum, 1); required_rate = 90000; /* "90 kHz clock rate MUST be used"*/ hintType = GF_RTP_PAYT_H264_AVC; streamType = GF_STREAM_VISUAL; avc_nalu_size = avcc->nal_unit_size; oti = GPAC_OTI_VIDEO_AVC; PL_ID = 0x0F; gf_odf_avc_cfg_del(avcc); } break; case GF_ISOM_SUBTYPE_3GP_QCELP: required_rate = 8000; hintType = GF_RTP_PAYT_QCELP; streamType = GF_STREAM_AUDIO; oti = GPAC_OTI_AUDIO_13K_VOICE; OfficialPayloadID = 12; nb_ch = 1; break; case GF_ISOM_SUBTYPE_3GP_EVRC: case GF_ISOM_SUBTYPE_3GP_SMV: required_rate = 8000; hintType = GF_RTP_PAYT_EVRC_SMV; streamType = GF_STREAM_AUDIO; oti = (TrackMediaSubType==GF_ISOM_SUBTYPE_3GP_EVRC) ? GPAC_OTI_AUDIO_EVRC_VOICE : GPAC_OTI_AUDIO_SMV_VOICE; nb_ch = 1; break; case GF_ISOM_SUBTYPE_3GP_DIMS: hintType = GF_RTP_PAYT_3GPP_DIMS; streamType = GF_STREAM_SCENE; break; case GF_ISOM_SUBTYPE_AC3: hintType = GF_RTP_PAYT_AC3; streamType = GF_STREAM_AUDIO; gf_isom_get_audio_info(file, TrackNum, 1, NULL, &nb_ch, NULL); break; default: /*ERROR*/ hintType = 0; break; } } /*not hintable*/ if (!hintType) return NULL; /*we only support self-contained files for hinting*/ gf_isom_get_data_reference(file, TrackNum, 1, &url, &urn); if (url || urn) return NULL; *e = GF_OUT_OF_MEM; GF_SAFEALLOC(tmp, GF_RTPHinter); if (!tmp) return NULL; /*override hinter type if requested and possible*/ if (has_mpeg4_mapping && (flags & GP_RTP_PCK_FORCE_MPEG4)) { hintType = GF_RTP_PAYT_MPEG4; avc_nalu_size = 0; } /*use static payload ID if enabled*/ else if (OfficialPayloadID && (flags & GP_RTP_PCK_USE_STATIC_ID) ) { PayloadID = OfficialPayloadID; } tmp->file = file; tmp->TrackNum = TrackNum; tmp->avc_nalu_size = avc_nalu_size; tmp->nb_chan = nb_ch; /*spatial scalability check*/ tmp->has_ctts = gf_isom_has_time_offset(file, TrackNum); /*get sample info*/ gf_media_get_sample_average_infos(file, TrackNum, &MinSize, &MaxSize, &avgTS, &maxDTSDelta, &const_dur, &bandwidth); /*systems carousel: we need at least IDX and RAP signaling*/ if (flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) { flags |= GP_RTP_PCK_SIGNAL_RAP; } /*update flags in MultiSL*/ if (flags & GP_RTP_PCK_USE_MULTI) { if (MinSize != MaxSize) flags |= GP_RTP_PCK_SIGNAL_SIZE; if (!const_dur) flags |= GP_RTP_PCK_SIGNAL_TS; } if (tmp->has_ctts) flags |= GP_RTP_PCK_SIGNAL_TS; /*default SL for RTP */ InitSL_RTP(&my_sl); my_sl.timestampResolution = gf_isom_get_media_timescale(file, TrackNum); /*override clockrate if set*/ if (required_rate) { Double sc = required_rate; sc /= my_sl.timestampResolution; maxDTSDelta = (u32) (maxDTSDelta*sc); my_sl.timestampResolution = required_rate; } /*switch to RTP TS*/ max_ptime = (u32) (max_ptime * my_sl.timestampResolution / 1000); my_sl.AUSeqNumLength = gf_get_bit_size(gf_isom_get_sample_count(file, TrackNum)); my_sl.CUDuration = const_dur; if (gf_isom_has_sync_points(file, TrackNum)) { my_sl.useRandomAccessPointFlag = 1; } else { my_sl.useRandomAccessPointFlag = 0; my_sl.hasRandomAccessUnitsOnlyFlag = 1; } if (is_crypted) { Bool use_sel_enc; gf_isom_get_ismacryp_info(file, TrackNum, 1, NULL, NULL, NULL, NULL, NULL, &use_sel_enc, &IV_length, &KI_length); if (use_sel_enc) flags |= GP_RTP_PCK_SELECTIVE_ENCRYPTION; } // in case a different timescale was provided tmp->OrigTimeScale = gf_isom_get_media_timescale(file, TrackNum); tmp->rtp_p = gf_rtp_builder_new(hintType, &my_sl, flags, tmp, MP4T_OnNewPacket, MP4T_OnPacketDone, /*if copy, no data ref*/ copy_media ? NULL : MP4T_OnDataRef, MP4T_OnData); //init the builder gf_rtp_builder_init(tmp->rtp_p, PayloadID, Path_MTU, max_ptime, streamType, oti, PL_ID, MinSize, MaxSize, avgTS, maxDTSDelta, IV_length, KI_length, mpeg4mode); /*ISMA compliance is a pain...*/ if (force_dts_delta) tmp->rtp_p->slMap.DTSDeltaLength = force_dts_delta; /* Hint Track Setup */ tmp->TrackID = gf_isom_get_track_id(file, TrackNum); tmp->HintID = tmp->TrackID + 65535; while (gf_isom_get_track_by_id(file, tmp->HintID)) tmp->HintID++; tmp->HintTrack = gf_isom_new_track(file, tmp->HintID, GF_ISOM_MEDIA_HINT, my_sl.timestampResolution); gf_isom_setup_hint_track(file, tmp->HintTrack, GF_ISOM_HINT_RTP); /*create a hint description*/ gf_isom_new_hint_description(file, tmp->HintTrack, -1, -1, 0, &descIndex); gf_isom_rtp_set_timescale(file, tmp->HintTrack, descIndex, my_sl.timestampResolution); if (hintType==GF_RTP_PAYT_MPEG4) { tmp->rtp_p->slMap.ObjectTypeIndication = oti; /*set this SL for extraction.*/ gf_isom_set_extraction_slc(file, TrackNum, 1, &my_sl); } tmp->bandwidth = bandwidth; /*set interleaving*/ gf_isom_set_track_group(file, TrackNum, InterleaveGroupID); if (!copy_media) { /*if we don't copy data set hint track and media track in the same group*/ gf_isom_set_track_group(file, tmp->HintTrack, InterleaveGroupID); } else { gf_isom_set_track_group(file, tmp->HintTrack, InterleaveGroupID + OFFSET_HINT_GROUP_ID); } /*use user-secified priority*/ InterleaveGroupPriority*=2; gf_isom_set_track_priority_in_group(file, TrackNum, InterleaveGroupPriority+1); gf_isom_set_track_priority_in_group(file, tmp->HintTrack, InterleaveGroupPriority); #if 0 /*QT FF: not setting these flags = server uses a random offset*/ gf_isom_rtp_set_time_offset(file, tmp->HintTrack, 1, 0); /*we don't use seq offset for maintainance pruposes*/ gf_isom_rtp_set_time_sequence_offset(file, tmp->HintTrack, 1, 0); #endif *e = GF_OK; return tmp; }