main.c

来自「gaca源码」· C语言 代码 · 共 1,695 行 · 第 1/4 页

C
1,695
字号
		if (!n->skip_impl) {
			fprintf(f, "\tcase TAG_MPEG4_%s: return %s_get_field_index(node, inField, code_mode, fieldIndex);\n", n->name, n->name);
		}
	}
	fprintf(f, "\tdefault:\n\t\treturn GF_BAD_PARAM;\n\t}\n}\n\n");

	fprintf(f, "Bool gf_sg_mpeg4_node_get_aq_info(GF_Node *node, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits)\n{\n\tswitch (node->sgprivate->tag) {\n");
	for (i=0; i<gf_list_count(BNodes); i++) {
		n = gf_list_get(BNodes, i);
		if (!n->skip_impl) {
			fprintf(f, "\tcase TAG_MPEG4_%s: return %s_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits);\n", n->name, n->name);
		}
	}
	fprintf(f, "\tdefault:\n\t\treturn 0;\n\t}\n}\n\n");

	fprintf(f, "u32 gf_sg_mpeg4_node_get_child_ndt(GF_Node *node)\n{\n\tswitch (node->sgprivate->tag) {\n");
	for (i=0; i<gf_list_count(BNodes); i++) {
		n = gf_list_get(BNodes, i);
		if (!n->skip_impl && strlen(n->Child_NDT_Name) ) {
			fprintf(f, "\tcase TAG_MPEG4_%s: return %s;\n", n->name, n->Child_NDT_Name);
		}
	}
	fprintf(f, "\tdefault:\n\t\treturn 0;\n\t}\n}\n\n");


	fprintf(f, "\nu32 gf_node_mpeg4_type_by_class_name(const char *node_name)\n{\n\tif(!node_name) return 0;\n");
	for (i=0; i<gf_list_count(BNodes); i++) {
		n = gf_list_get(BNodes, i);
		if (n->skip_impl) continue;
		fprintf(f, "\tif (!strcmp(node_name, \"%s\")) return TAG_MPEG4_%s;\n", n->name, n->name);
	}
	fprintf(f, "\treturn 0;\n}\n\n");


	EndFile(f, "", 1);
}

void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs, u32 version)
{
	char sLine[2000];
	char token[100];
	char *p;
	BNode *n;
	BField *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();
				n->version = version;
				gf_list_add(BNodes, n);

				//get its name
				GetNextToken(n->name, " \t[");
				if (!strcmp(n->name, "TimeSensor")) {
					n = n;
				}

				//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 = malloc(strlen(token)+1);
					strcpy(p, token);
					gf_list_add(n->NDT, p);
				}

				//extract the coding type
				if (strcmp(token, "%COD")) {
					printf("Corrupted template file\n");
					return;
				} else {
					GetNextToken(token, "= ");
					if (token[0] == 'N') {
						n->codingType = 0;
					} else {
						n->codingType = 1;
					}
				}
			}
			//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, "FIX_MAX");
						} else if (!strcmp(f->def, "-I")) {
							strcpy(f->def, "FIX_MIN");
						}
					} else if (!strcmp(f->familly, "SFTime")) {
						if (!strcmp(f->def, "+I") || !strcmp(f->def, "I")) {
							strcpy(f->def, "FIX_MAX");
						} else if (!strcmp(f->def, "-I")) {
							strcpy(f->def, "FIX_MIN");
						}
					} 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':
						f->hasBounds = 1;
						GetNextToken(f->b_min, "[(,");
						GetNextToken(f->b_max, ")]");
						break;
					case 'q':
						f->hasQuant = 1;
						GetNextToken(f->quant_type, " \t");
						if (!strcmp(f->quant_type, "13"))
							GetNextToken(f->qt13_bits, " \t");
						break;
					case 'a':
						f->hasAnim = 1;
						GetNextToken(token, " \t");
						f->AnimType = atoi(token);
						break;
					default:
						break;
					}
				}
			}
		}
	}


	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;
		}
	}
}


void WriteNodeDump(FILE *f, BNode *n)
{
	BField *bf;
	u32 i;

	fprintf(f, "static const char *%s_FieldName[] = {\n", n->name);
	for (i=0; i<gf_list_count(n->Fields); i++) {
		bf = gf_list_get(n->Fields, i);
		if (!i) {
			fprintf(f, " \"%s\"", bf->name);
		} else {
			fprintf(f, ", \"%s\"", bf->name);
		}
	}
	fprintf(f, "\n};\n\n");
}

void parse_profile(GF_List *nodes, FILE *prof)
{
	char sLine[2000];
	BNode *n;
	Bool found;
	u32 i;

	while (!feof(prof)) {
		fgets(sLine, 2000, prof);
		//skip comment and empty lines
		if (sLine[0] == '#') continue;
		if (sLine[0] == '\n') continue;
		if (strstr(sLine, "Proximity")) 
			found = 0;
		found = 1;
		while (found) {
			switch (sLine[strlen(sLine)-1]) {
			case '\n':
			case '\r':
			case ' ':
				sLine[strlen(sLine)-1] = 0;
				break;
			default:
				found = 0;
				break;
			}
		}

//		if (0 && !stricmp(sLine, "Appearance") || !stricmp(sLine, "Shape") || !stricmp(sLine, "Sound2D") ) {
		if (0) {
			printf("Warning: cannot disable node %s (required in all BIFS profiles)\n", sLine);
		} else {
			found = 0;
			for (i=0; i<gf_list_count(nodes); i++) {
				n = gf_list_get(nodes, i);
				if (!stricmp(n->name, sLine)) {
					n->skip_impl = 1;
					found = 1;
					break;
				}
			}
			if (!found) printf("cannot disable %s: node not found\n", sLine);
		}
	}
}

int main (int argc, char **argv)
{
	FILE *nodes, *ndt_c, *ndt_h, *fskip;
	GF_List *BNodes, *NDTs;
	u32 i, j, nbVersion;
	BNode *n;
	BField *bf;

	if (argc < 2) {
		PrintUsage();
		return 0;
	}

	BNodes = gf_list_new();
	NDTs = gf_list_new();



	fskip = NULL;
	i=1;
	if (argv[i][0]=='-') {
		fskip = fopen(argv[i+1], "rt");
		if (!fskip) {
			printf("file %s not found\n", argv[i+1]);
			return 0;
		}
		i+=2;
	}
	nbVersion = 1;
	for (; i<(u32)argc; i++) {
		nodes = fopen(argv[i], "rt");
		//all nodes are in the same list but we keep version info
		ParseTemplateFile(nodes, BNodes, NDTs, nbVersion);
		

		//special case for viewport: it is present in V1 but empty
		if (nbVersion==1) CheckInTable("SFViewportNode", NDTs);
		nbVersion++;
		fclose(nodes);
	}
	nbVersion--;
	printf("BIFS tables parsed: %d versions\n", nbVersion);
	
	if (fskip) {
		parse_profile(BNodes, fskip);
		fclose(fskip);
	}

	//write the nodes def
	WriteNodesFile(BNodes, NDTs, nbVersion);
	//write all nodes init stuff
	WriteNodeCode(BNodes);

	//write all NDTs
	ndt_h = BeginFile("NDT", 0);
	ndt_c = BeginFile("NDT", 1);

	fprintf(ndt_h, "#include <gpac/nodes_mpeg4.h>\n\n");
	fprintf(ndt_c, "\n\n#include <gpac/internal/bifs_tables.h>\n");
	
	//prepare the encoding file
	fprintf(ndt_h, "\n\nu32 ALL_GetNodeType(const u32 *table, const u32 count, u32 NodeTag, u32 Version);\n\n");
	fprintf(ndt_c, "\n\nu32 ALL_GetNodeType(const u32 *table, const u32 count, u32 NodeTag, u32 Version)\n{\n\tu32 i = 0;");
	fprintf(ndt_c, "\n\twhile (i<count) {\n\t\tif (table[i] == NodeTag) goto found;\n\t\ti++;\n\t}\n\treturn 0;\nfound:\n\tif (Version == 2) return i+2;\n\treturn i+1;\n}\n\n");

	//write the NDT
	for (i=0; i<nbVersion; i++) {
		//write header
		WriteNDT_H(ndt_h, BNodes, NDTs, i+1);
		//write decoding code
		WriteNDT_Dec(ndt_c, BNodes, NDTs, i+1);
		//write encoding code
		WriteNDT_Enc(ndt_c, BNodes, NDTs, i+1);
	}



	fprintf(ndt_c, "\n\nu32 gf_bifs_ndt_get_node_type(u32 NDT_Tag, u32 NodeType, u32 Version)\n{\n\tswitch (Version) {\n");
	for (i=0; i<nbVersion; i++) {
		fprintf(ndt_c, "\tcase GF_BIFS_V%d:\n\t\treturn NDT_V%d_GetNodeTag(NDT_Tag, NodeType);\n", i+1, i+1);
	}
	fprintf(ndt_c, "\tdefault:\n\t\treturn 0;\n\t}\n}");

	fprintf(ndt_c, "\n\nu32 gf_bifs_get_ndt_bits(u32 NDT_Tag, u32 Version)\n{\n\tswitch (Version) {\n");
	for (i=0; i<nbVersion; i++) {
		fprintf(ndt_c, "\tcase GF_BIFS_V%d:\n\t\treturn NDT_V%d_GetNumBits(NDT_Tag);\n", i+1, i+1);
	}
	fprintf(ndt_c, "\tdefault:\n\t\treturn 0;\n\t}\n}");

	fprintf(ndt_c, "\n\nu32 gf_bifs_get_node_type(u32 NDT_Tag, u32 NodeTag, u32 Version)\n{\n\tswitch (Version) {\n");
	for (i=0; i<nbVersion; i++) {
		fprintf(ndt_c, "\tcase GF_BIFS_V%d:\n\t\treturn NDT_V%d_GetNodeType(NDT_Tag, NodeTag);\n", i+1, i+1);
	}
	fprintf(ndt_c, "\tdefault:\n\t\treturn 0;\n\t}\n}");	

	fprintf(ndt_h, "\nu32 NDT_GetChildTable(u32 NodeTag);\n");
	fprintf(ndt_h, "\n\n");
	
	//NDT checking
	fprintf(ndt_c, "u32 GetChildrenNDT(GF_Node *node)\n{\n\tif (!node) return 0;\n\tswitch (gf_node_get_tag(node)) {\n");
	for (i=0; i<gf_list_count(BNodes); i++) {
		n = gf_list_get(BNodes, i);
		if (n->skip_impl) continue;
		for (j=0; j<gf_list_count(n->Fields); j++) {
			bf = gf_list_get(n->Fields, j);
			if (!strcmp(bf->name, "children")) {
				fprintf(ndt_c, "\tcase TAG_MPEG4_%s:\n\t\treturn NDT_SF%s;\n", n->name, bf->familly+2);
				break;
			}
		}
	}
	fprintf(ndt_c, "\tdefault:\n\t\treturn 0;\n\t}\n}\n\n");

	EndFile(ndt_h, "NDT", 0);
	EndFile(ndt_c, "", 1);
	
	//free NDTs
	while (gf_list_count(NDTs)) {
		char *tmp = gf_list_get(NDTs, 0);
		free(tmp);
		gf_list_rem(NDTs, 0);
	}
	gf_list_del(NDTs);
	//free nodes
	while (gf_list_count(BNodes)) {
		n = gf_list_get(BNodes, 0);
		gf_list_rem(BNodes, 0);
		while (gf_list_count(n->NDT)) {
			char *tmp = gf_list_get(n->NDT, 0);
			free(tmp);
			gf_list_rem(n->NDT, 0);
		}
		gf_list_del(n->NDT);
		while (gf_list_count(n->Fields)) {
			bf = gf_list_get(n->Fields, 0);
			free(bf);
			gf_list_rem(n->Fields, 0);
		}
		gf_list_del(n->Fields);
		free(n);
	}
	gf_list_del(BNodes);

	return 0;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?