예제 #1
0
파일: com_enc.c 프로젝트: bigbensk/gpac
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;
}
예제 #2
0
파일: com_enc.c 프로젝트: bigbensk/gpac
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;
}
예제 #3
0
파일: script_enc.c 프로젝트: ARSekkat/gpac
void SFE_PutIdentifier(ScriptEnc *sc_enc, char *id)
{
	u32 i;
	u32 nbBits, length;
	char *str;

	if (sc_enc->emul) return;

	i=0;
	while ((str = (char *)gf_list_enum(sc_enc->identifiers, &i))) {
		if (strcmp(str, id)) continue;

		nbBits = 0;
		length = gf_list_count(sc_enc->identifiers) - 1;
		while (length > 0) {
			length >>= 1;
			nbBits ++;
		}
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "received", str);
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, i-1, nbBits, "identifierCode", str);
		return;
	}
	GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "received", id);
	gf_list_add(sc_enc->identifiers, gf_strdup(id));
	gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, id);
}
예제 #4
0
GF_Err gf_bifs_enc_node(GF_BifsEncoder * codec, GF_Node *node, u32 NDT_Tag, GF_BitStream *bs, GF_Node *parent_node)
{
	u32 NDTBits, node_type, node_tag, BVersion, node_id;
	const char *node_name;
	Bool flag, reset_qp14;
	GF_Node *new_node;
	GF_Err e;

	assert(codec->info);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[BIFS] Encode node %s\n", gf_node_get_class_name(node) ));

	/*NULL node is a USE of maxID*/
	if (!node) {
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "USE", NULL);
		GF_BIFS_WRITE_INT(codec, bs, (1<<codec->info->config.NodeIDBits) - 1 , codec->info->config.NodeIDBits, "NodeID", "NULL");
		return GF_OK;
	}

	flag = BE_NodeIsUSE(codec, node);
	GF_BIFS_WRITE_INT(codec, bs, flag ? 1 : 0, 1, "USE", (char*)gf_node_get_class_name(node));

	if (flag) {
		gf_bs_write_int(bs, gf_node_get_id(node) - 1, codec->info->config.NodeIDBits);
		new_node = gf_bifs_enc_find_node(codec, gf_node_get_id(node) );
		if (!new_node)
			return codec->LastError = GF_SG_UNKNOWN_NODE;

		/*restore QP14 length*/
		switch (gf_node_get_tag(new_node)) {
		case TAG_MPEG4_Coordinate:
		{
			u32 nbCoord = ((M_Coordinate *)new_node)->point.count;
			gf_bifs_enc_qp14_enter(codec, GF_TRUE);
			gf_bifs_enc_qp14_set_length(codec, nbCoord);
			gf_bifs_enc_qp14_enter(codec, GF_FALSE);
		}
		break;
		case TAG_MPEG4_Coordinate2D:
		{
			u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count;
			gf_bifs_enc_qp14_enter(codec, GF_TRUE);
			gf_bifs_enc_qp14_set_length(codec, nbCoord);
			gf_bifs_enc_qp14_enter(codec, GF_FALSE);
		}
		break;
		}
		return GF_OK;
	}

	BVersion = GF_BIFS_V1;
	node_tag = node->sgprivate->tag;
	while (1) {
		node_type = gf_bifs_get_node_type(NDT_Tag, node_tag, BVersion);
		NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion);
		if (BVersion==2 && (node_tag==TAG_ProtoNode)) node_type = 1;
		GF_BIFS_WRITE_INT(codec, bs, node_type, NDTBits, "ndt", NULL);
		if (node_type) break;

		BVersion += 1;
		if (BVersion > GF_BIFS_NUM_VERSION) {
			if (parent_node) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s as a child of %s\n", gf_node_get_class_name(node), gf_node_get_class_name(parent_node) ));
			} else {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s in the SFWorldNode context\n", gf_node_get_class_name(node) ));
			}
			return codec->LastError = GF_BIFS_UNKNOWN_VERSION;
		}
	}
	if (BVersion==2 && node_type==1) {
		GF_Proto *proto = ((GF_ProtoInstance *)node)->proto_interface;
		GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL);
	}

	/*special handling of 3D mesh*/

	/*DEF'd node*/
	node_name = gf_node_get_name_and_id(node, &node_id);
	GF_BIFS_WRITE_INT(codec, bs, node_id ? 1 : 0, 1, "DEF", NULL);
	if (node_id) {
		GF_BIFS_WRITE_INT(codec, bs, node_id - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
		if (codec->UseName) gf_bifs_enc_name(codec, bs, (char*) node_name );
	}

	/*no updates of time fields for now - NEEDED FOR A LIVE ENCODER*/

	/*if coords were not stored for QP14 before coding this node, reset QP14 it when leaving*/
	reset_qp14 = !codec->coord_stored;

	/*QP14 case*/
	switch (node_tag) {
	case TAG_MPEG4_Coordinate:
	case TAG_MPEG4_Coordinate2D:
		gf_bifs_enc_qp14_enter(codec, GF_TRUE);
	}

	e = EncNodeFields(codec, bs, node);
	if (e) return e;

	if (codec->coord_stored && reset_qp14)
		gf_bifs_enc_qp14_reset(codec);

	switch (node_tag) {
	case TAG_MPEG4_Coordinate:
	case TAG_MPEG4_Coordinate2D:
		gf_bifs_enc_qp14_enter(codec, GF_FALSE);
		break;
	}
	return GF_OK;
}
예제 #5
0
파일: script_enc.c 프로젝트: Kurtnoise/gpac
static GF_Err EncScriptFields(ScriptEnc *sc_enc)
{
	u32 nbFields, nbBits, eType, nbBitsProto, i;
	Bool use_list;
	GF_Err e;
	GF_FieldInfo info;

	nbFields = gf_node_get_num_fields_in_mode(sc_enc->script, GF_SG_FIELD_CODING_ALL) - 3;
	use_list = 1;
	nbBits = gf_get_bit_size(nbFields);
	if (nbFields+1 > 4 + gf_get_bit_size(nbFields)) use_list = 0;
	if (!nbFields) {
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "Script::isList", NULL);
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "end", NULL);
		return GF_OK;
	}
	GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, use_list ? 1 : 0, 1, "Script::isList", NULL);
	if (!use_list) {
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbBits, 4, "nbBits", NULL);
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbFields, nbBits, "count", NULL);
	}

	nbBitsProto = 0;
	if (sc_enc->codec->encoding_proto) nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(sc_enc->codec->encoding_proto) - 1);

	for (i=0; i<nbFields; i++) {
		if (use_list) GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "end", NULL);

		gf_node_get_field(sc_enc->script, i+3, &info);
		switch (info.eventType) {
		case GF_SG_EVENT_IN:
			eType = GF_SG_SCRIPT_TYPE_EVENT_IN;
			break;
		case GF_SG_EVENT_OUT:
			eType = GF_SG_SCRIPT_TYPE_EVENT_OUT;
			break;
		default:
			eType = GF_SG_SCRIPT_TYPE_FIELD;
			break;
		}
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, eType, 2, "eventType", NULL);
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, info.fieldType, 6, "fieldType", NULL);
		gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, (char *) info.name);
		/*this is an identifier for script*/
		gf_list_add(sc_enc->identifiers, gf_strdup(info.name));

		if (sc_enc->codec->encoding_proto) {
			GF_Route *isedField = gf_bifs_enc_is_field_ised(sc_enc->codec, sc_enc->script, i+3);
			if (isedField) {
				GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "isedField", NULL);

				if (isedField->ToNode == sc_enc->script) {
					GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL);
				} else {
					GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL);
				}
				continue;
			}
			GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "isedField", NULL);
		}
		/*default value*/
		if (eType == GF_SG_SCRIPT_TYPE_FIELD) {
			GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, (info.far_ptr) ? 1 : 0, 1, "hasInitialValue", NULL);
			if (info.far_ptr) {
				e = gf_bifs_enc_field(sc_enc->codec, sc_enc->bs, sc_enc->script, &info);
				if (e) return e;
			}
		}
	}
	if (use_list) GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "end", NULL);
	return GF_OK;
}
예제 #6
0
파일: script_enc.c 프로젝트: Kurtnoise/gpac
u32 SFE_Expression(ScriptEnc *sc_enc, u32 start, u32 end, Bool memberAccess)
{
	char *str;
	u32 n = start;
	u32 curPos = 0, finalPos = 0;
	u32 curTok, prevTok;
	u32 curExpr = 0, expr = 0;
	u32 curRank, maxRank=0;

	if (sc_enc->err) return 0;

	curTok = prevTok = sc_enc->expr_toks[n];
	do {
		curPos = n;
		switch (curTok) {
		case TOK_IDENTIFIER:
			curExpr = ET_IDENTIFIER;
			break;
		case TOK_NUMBER:
			curExpr = ET_NUMBER;
			break;
        case TOK_BOOLEAN:
            curExpr = ET_BOOLEAN;
            break;
		case TOK_STRING:
			curExpr = ET_STRING;
			break;
		case TOK_LEFT_CURVE:
			if (prevTok == TOK_IDENTIFIER) curExpr = ET_FUNCTION_CALL;
			else curExpr = ET_CURVED_EXPR;
			n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n, end);
			curTok = TOK_RIGHT_CURVE;
			break;
		case TOK_LEFT_BRACKET:
			curExpr = ET_ARRAY_DEREFERENCE;
			n = MoveToToken(sc_enc, TOK_RIGHT_BRACKET, n, end);
			curTok = TOK_RIGHT_BRACKET;
			break;
		case TOK_PERIOD:
			curTok = sc_enc->expr_toks[++n];
			CHECK_TOK(TOK_IDENTIFIER);
			if (sc_enc->expr_toks[n+1] == TOK_LEFT_CURVE) {
				curExpr = ET_OBJECT_METHOD_CALL;
				n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n+1, end);
				curTok = TOK_RIGHT_CURVE;
			} else {
				curExpr = ET_OBJECT_MEMBER_ACCESS;
			}
			break;
		case TOK_NEW:
			curExpr = ET_NEW;
			curTok = sc_enc->expr_toks[++n];
			CHECK_TOK(TOK_IDENTIFIER);
			curTok = sc_enc->expr_toks[++n];
			CHECK_TOK(TOK_LEFT_CURVE);
			n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n, end);
			curTok = TOK_RIGHT_CURVE;
			break;
		case TOK_FUNCTION:
			curExpr = ET_FUNCTION_ASSIGN;
			break;
		case TOK_PLUS:
			if (
				prevTok==TOK_RIGHT_CURVE || prevTok==TOK_RIGHT_BRACKET ||
				prevTok==TOK_IDENTIFIER || prevTok==TOK_NUMBER ||
				prevTok==TOK_STRING || prevTok==TOK_INCREMENT ||
				prevTok==TOK_DECREMENT
			) {
				curExpr = ET_PLUS;
			} else {
				goto skip_token;
			}
			break;
		case TOK_MINUS:
			if (
				prevTok==TOK_RIGHT_CURVE || prevTok==TOK_RIGHT_BRACKET ||
				prevTok==TOK_IDENTIFIER || prevTok==TOK_NUMBER ||
				prevTok==TOK_STRING || prevTok==TOK_INCREMENT ||
				prevTok==TOK_DECREMENT
			) {
				curExpr = ET_MINUS;
			} else {
				curExpr = ET_NEGATIVE;
				curTok = TOK_NEGATIVE;
			}
			break;
		case TOK_INCREMENT:
			curExpr = ET_INCREMENT;
			break;
		case TOK_DECREMENT:
			curExpr = ET_DECREMENT;
			break;
		case TOK_NOT:
			curExpr = ET_NOT;
			break;
		case TOK_ONESCOMP:
			curExpr = ET_ONESCOMP;
			break;
		case TOK_CONDTEST:
			curExpr = ET_CONDTEST;
			break;
		case TOK_CONDSEP:
			break;
		case TOK_LEFT_BRACE:
			curExpr = ET_CURVED_EXPR;
			n = MoveToToken(sc_enc, TOK_RIGHT_BRACE, n, end);
			curTok = TOK_RIGHT_BRACE;
			break;
			break;
		default:

			if (curTok && (curTok != TOK_VAR)  
				&& (curTok < TOK_MULTIPLY || curTok > TOK_OREQ)) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal token %s read\n", tok_names[curTok]));
				sc_enc->err = GF_BAD_PARAM;
				return 0;
			}
			curExpr = TOK_To_ET(curTok);
		}

		if (curTok == TOK_CONDSEP) {
			prevTok = curTok;
			curTok = sc_enc->expr_toks[++n];
			continue;
		}
		curRank = ET_Rank[curExpr];
		if (curRank > maxRank) {
			maxRank = curRank;
			expr = curExpr;
			finalPos = curPos;
		} else if (curRank == maxRank && ET_leftAssoc[curRank]) {
			expr = curExpr;
			finalPos = curPos;
		}
		prevTok = curTok;
skip_token:
		curTok = sc_enc->expr_toks[++n];
	} while (n<end);

	if (expr == ET_INCREMENT) {
		if (finalPos==start) {}
		else if (finalPos==end-1) expr = ET_POST_INCREMENT;
		else {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal Increment expression\n"));
			sc_enc->err = GF_BAD_PARAM;
			return expr;
		}
	} else if (expr == ET_DECREMENT) {
		if (finalPos==start) {}
		else if (finalPos==end-1) expr = ET_POST_DECREMENT;
		else {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal Decrement expression\n"));
			sc_enc->err = GF_BAD_PARAM;
			return expr;
		}
	}
	
	SFE_WRITE_INT(sc_enc, expr, NUMBITS_EXPR_TYPE, "expressionType", (char *) expr_name[expr]);

	switch (expr) {
	case ET_MULTIPLY:
	case ET_DIVIDE:
	case ET_MOD:
	case ET_PLUS:
	case ET_MINUS:
	case ET_LSHIFT:
	case ET_RSHIFT:
	case ET_RSHIFTFILL:
	case ET_LT:
	case ET_LE:
	case ET_GT:
	case ET_GE:
	case ET_EQ:
	case ET_NE:
	case ET_AND:
	case ET_XOR:
	case ET_OR:
	case ET_LAND:
	case ET_LOR:
		SFE_Expression(sc_enc, start, finalPos, 0);
		SFE_Expression(sc_enc, finalPos+1, end, 0);
		break;
	case ET_ASSIGN:
	case ET_PLUSEQ:
	case ET_MINUSEQ:
	case ET_MULTIPLYEQ:
	case ET_DIVIDEEQ:
	case ET_MODEQ:
	case ET_LSHIFTEQ:
	case ET_RSHIFTEQ:
	case ET_RSHIFTFILLEQ:
	case ET_ANDEQ:
	case ET_XOREQ:
	case ET_OREQ:
	{
		u32 ret = SFE_Expression(sc_enc, start, finalPos, 0);
		if ( ret != ET_IDENTIFIER && ret != ET_OBJECT_MEMBER_ACCESS && ret != ET_ARRAY_DEREFERENCE ) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: LeftVariable expected, %s returned\n", expr_name[ret]));
			sc_enc->err = GF_BAD_PARAM;
			return expr;
		}
		SFE_Expression(sc_enc, finalPos+1, end, 0);
	}
		break;

	case ET_IDENTIFIER:
		str = (char *)gf_list_get(sc_enc->id_buf, 0);
		gf_list_rem(sc_enc->id_buf, 0);
		/*TODO: when accessing member, we should try to translate proto fields into _fieldALL when not
		using USENAMEs...*/
		if (memberAccess) {
		}
		SFE_PutIdentifier(sc_enc, str);
		gf_free(str);
		break;
	case ET_NUMBER:
		str = (char *)gf_list_get(sc_enc->id_buf, 0);
		gf_list_rem(sc_enc->id_buf, 0);
		SFE_PutNumber(sc_enc, str);
		gf_free(str);
		break;
    case ET_BOOLEAN:
		str = (char *)gf_list_get(sc_enc->id_buf, 0);
		gf_list_rem(sc_enc->id_buf, 0);
		SFE_PutBoolean(sc_enc, str);
		gf_free(str);
		break;
    case ET_VAR:
		while (1) {
			str = (char *)gf_list_get(sc_enc->id_buf, 0);
			if (!str) break;
			gf_list_rem(sc_enc->id_buf, 0);
			GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "hasArgument", NULL);
			SFE_PutIdentifier(sc_enc, str);
			gf_free(str);
		}
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "hasArgument", NULL);
		break;
	case ET_STRING:
		str = (char *)gf_list_get(sc_enc->id_buf, 0);
		gf_list_rem(sc_enc->id_buf, 0);
		if (!sc_enc->emul) gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, str);
		gf_free(str);
		break;
	case ET_NEGATIVE:
	case ET_INCREMENT:
	case ET_DECREMENT:
	case ET_NOT:
	case ET_ONESCOMP:
		SFE_Expression(sc_enc, finalPos+1, end, 0);
		break;
	case ET_CURVED_EXPR:
		SFE_CompoundExpression(sc_enc, finalPos+1, end-1, 0);
		break;
	case ET_POST_INCREMENT :
	case ET_POST_DECREMENT :
		SFE_Expression(sc_enc, start, finalPos, 0);
		break;
	case ET_FUNCTION_CALL:
		SFE_FunctionCall(sc_enc, start, end);
		break;
	case ET_OBJECT_MEMBER_ACCESS :
		SFE_ObjectMemberAccess(sc_enc, start, finalPos, end);
		break;
	case ET_OBJECT_METHOD_CALL:
		SFE_ObjectMethodCall(sc_enc, start, finalPos, end);
		break;
	case ET_ARRAY_DEREFERENCE:
		SFE_ArrayDereference(sc_enc, start, finalPos, end);
		break;
	case ET_NEW:
		SFE_ObjectConstruct(sc_enc, start, finalPos, end);
		break;
	case ET_CONDTEST:
		SFE_ConditionTest(sc_enc, start, finalPos, end);
		break;
	case ET_FUNCTION_ASSIGN:
		SFE_NextToken(sc_enc);
		SFE_CheckToken(sc_enc, TOK_LEFT_CURVE);

		SFE_Arguments(sc_enc);
		SFE_StatementBlock(sc_enc);
		SFE_NextToken(sc_enc);
		SFE_CheckToken(sc_enc, TOK_SEMICOLON);
		break;
	default:
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: illegal expression type %s\n", expr_name[expr]));
		sc_enc->err = GF_BAD_PARAM;
		break;
	}
	return expr;
}
예제 #7
0
파일: com_enc.c 프로젝트: bigbensk/gpac
GF_Err BE_EncProtoList(GF_BifsEncoder *codec, GF_List *protoList, GF_BitStream *bs)
{
	u8 useQuant, useAnim;
	u32 i, j, nbRoutes, nbBits, numProtos, numFields, count;
	GF_Node *node;
	GF_ProtoFieldInterface *proto_field;
	GF_Proto *proto, *prev_proto;
	GF_Route *r;
	GF_Err e;
	GF_SceneGraph *rootSG;
	GF_FieldInfo field;

	e = GF_OK;
	if (!protoList || !gf_list_count(protoList)) {
		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL);
		return GF_OK;
	}
	if (!codec->info->config.ProtoIDBits) 
		return GF_NON_COMPLIANT_BITSTREAM;

	/*store state*/
	rootSG = codec->current_proto_graph;
	prev_proto = codec->encoding_proto;

	numProtos = gf_list_count(protoList);
	for (i=0; i<numProtos; i++) {
		proto = (GF_Proto*)gf_list_get(protoList, i);
		useQuant = useAnim = 0;
		/*set current proto state*/
		codec->encoding_proto = proto;
		codec->current_proto_graph = proto->sub_graph;

		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreProto", NULL);

		/*1- proto interface declaration*/
		GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL);

		if (codec->UseName) gf_bifs_enc_name(codec, bs, proto->Name);

		numFields = gf_list_count(proto->proto_fields);
		for (j=0; j<numFields; j++) {
			proto_field = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, j);

			GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreField", NULL);
			GF_BIFS_WRITE_INT(codec, bs, proto_field->EventType, 2, "eventType", NULL);
			GF_BIFS_WRITE_INT(codec, bs, proto_field->FieldType, 6, "fieldType", NULL);
			
			if (codec->UseName) gf_bifs_enc_name(codec, bs, proto_field->FieldName);
			switch (proto_field->EventType) {
			case GF_SG_EVENT_EXPOSED_FIELD:
			case GF_SG_EVENT_FIELD:
				gf_sg_proto_field_get_field(proto_field, &field);
				if (gf_sg_vrml_is_sf_field(field.fieldType)) {
					e = gf_bifs_enc_sf_field(codec, bs, NULL, &field);
				} else {
					if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL);
					e = gf_bifs_enc_mf_field(codec, bs, NULL, &field);
				}
				if (e) goto exit;
				break;
			}
			if (proto_field->QP_Type) useQuant = 1;
			if (proto_field->Anim_Type) useAnim = 1;
		}
		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreField", NULL);
		
		GF_BIFS_WRITE_INT(codec, bs, proto->ExternProto.count ? 1 : 0, 1, "externProto", NULL);
		/*externProto*/
		if (proto->ExternProto.count) {
			memset(&field, 0, sizeof(GF_FieldInfo));
			field.far_ptr = &proto->ExternProto;
			field.fieldType = GF_SG_VRML_MFURL;
			field.name = "ExternProto";

			if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL);
			e = gf_bifs_enc_mf_field(codec, bs, NULL, &field);
			if (e) goto exit;
		} else {
			/*encode sub-proto list*/
			e = BE_EncProtoList(codec, proto->sub_graph->protos, bs);
			if (e) goto exit;

			count = gf_list_count(proto->node_code);
			/*BIFS cannot encode empty protos ! We therefore encode a NULL node instead*/
			if (!count) {
				gf_bifs_enc_node(codec, NULL, NDT_SFWorldNode, bs);
				GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreNodes", NULL);
			} else {
				for (j=0; j<count; j++) {
					/*parse all nodes in SFWorldNode table*/
					node = (GF_Node*)gf_list_get(proto->node_code, j);
					e = gf_bifs_enc_node(codec, node, NDT_SFWorldNode, bs);
					if (e) goto exit;
					GF_BIFS_WRITE_INT(codec, bs, (j+1==count) ? 0 : 1, 1, "moreNodes", NULL);
				}
			}

			/*encode routes routes*/
			nbRoutes = count = gf_list_count(proto->sub_graph->Routes);
			for (j=0; j<count; j++) {
				r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j);
				if (r->IS_route) nbRoutes--;
			}

			GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "hasRoute", NULL);
			if (nbRoutes) {
				nbBits = gf_get_bit_size(nbRoutes);
				if (nbBits + 5 > nbRoutes) {
					GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL);
					/*list*/
					for (j=0; j<count; j++) {
						r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j);
						if (r->IS_route) continue;
						e = gf_bifs_enc_route(codec, r, bs);
						if (e) goto exit;
						nbRoutes--;
						GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 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, nbRoutes, nbBits, "length", NULL);
					for (j=0; j<count; j++) {
						r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j);
						if (r->IS_route) continue;
						e = gf_bifs_enc_route(codec, r, bs);
						if (e) goto exit;
					}
				}
			}
		}

		/*anim and Quantization stuff*/
		GF_BIFS_WRITE_INT(codec, bs, useQuant, 1, "useQuant", NULL);
		GF_BIFS_WRITE_INT(codec, bs, useAnim, 1, "useAnim", NULL);

		if (!useAnim && !useQuant) continue;

		count = gf_sg_proto_get_field_count(proto);
		for (j=0; j<count; j++) {
			proto_field = gf_sg_proto_field_find(proto, j);
			gf_sg_proto_field_get_field(proto_field, &field);

			/*quant*/
			if (useQuant && ( (field.eventType == GF_SG_EVENT_FIELD) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) {
				GF_BIFS_WRITE_INT(codec, bs, proto_field->QP_Type, 4, "QPType", NULL);
				if (proto_field->QP_Type==QC_LINEAR_SCALAR) GF_BIFS_WRITE_INT(codec, bs, proto_field->NumBits, 5, "nbBits", NULL);
				GF_BIFS_WRITE_INT(codec, bs, proto_field->hasMinMax, 1, "hasMinMax", NULL);
				if (proto_field->hasMinMax) {
					field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
					switch (field.fieldType) {
					case GF_SG_VRML_SFINT32:
					case GF_SG_VRML_SFTIME:
						break;
					default:
						field.fieldType = GF_SG_VRML_SFFLOAT;
						break;
					}
					field.name = "QPMinValue";
					field.far_ptr = proto_field->qp_min_value;
					gf_bifs_enc_sf_field(codec, bs, NULL, &field);

					field.name = "QPMaxValue";
					field.far_ptr = proto_field->qp_max_value;
					gf_bifs_enc_sf_field(codec, bs, NULL, &field);
				}
			}

			/*anim - not supported yet*/
			if (useAnim && ( (field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) {
				e = GF_NOT_SUPPORTED;
				goto exit;
			}
		}
	}
	GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL);

exit:
	/*restore scene graph state*/
	codec->encoding_proto = prev_proto;
	codec->current_proto_graph = rootSG;
	return e;
}