📄 main.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / MPEG4 Scene Graph Generator sub-project * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <gpac/list.h>#include <time.h>#define COPYRIGHT_SCENE "/*\n * GPAC - Multimedia Framework C SDK\n *\n * Copyright (c) Jean Le Feuvre 2000-2005\n * All rights reserved\n *\n * This file is part of GPAC / Scene Graph sub-project\n *\n * GPAC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation; either version 2, or (at your option)\n * any later version.\n *\n * GPAC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details. \n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; see the file COPYING. If not, write to\n * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"#define COPYRIGHT_BIFS "/*\n * GPAC - Multimedia Framework C SDK\n *\n * Copyright (c) Jean Le Feuvre 2000-2005\n * All rights reserved\n *\n * This file is part of GPAC / BIFS codec sub-project\n *\n * GPAC is free software; you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation; either version 2, or (at your option)\n * any later version.\n *\n * GPAC is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details. \n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; see the file COPYING. If not, write to\n * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n */\n"static char *CurrentLine;void PrintUsage(){ printf("MPEG4Gen [-p file] template_file_v1 (template_file_v2 ...)\n" "\nGPAC MPEG4 Scene Graph generator. Usage:\n" "-p: listing file of nodes to exclude from tables\n" "Template files MUST be fed in order\n" "\n" "Generated Files are directly updated in the GPAC distribution - do NOT try to change this\n\n" "Written by Jean Le Feuvre - (c) 2000-2005\n" );}//a node fieldtypedef struct{ char type[50]; //SFxxx, MFxxx char familly[50]; //name char name[1000]; //default value char def[100]; //bounds u32 hasBounds; char b_min[20]; char b_max[20]; //Quant u32 hasQuant; char quant_type[50]; char qt13_bits[50]; //Anim u32 hasAnim; u32 AnimType;} BField;//NDTs//a BIFS nodetypedef struct{ char name[1000]; //NDT info. NDT are created in alphabetical order GF_List *NDT; //0: normal, 1: special u32 codingType; u32 version; GF_List *Fields; //coding types u8 hasDef, hasIn, hasOut, hasDyn; u8 hasAQInfo; u8 hasDefault; u8 skip_impl; char Child_NDT_Name[1000];} BNode;void skip_sep(char *sep){ //skip separaors while (*CurrentLine && strchr(sep, *CurrentLine)) { CurrentLine = CurrentLine + 1; //end of line - no token if (*CurrentLine == '\n') return; }}//note that we increment the line no matter whatu32 GetNextToken(char *token, char *sep){ u32 i , j = 0; strcpy(token, ""); //skip separaors while (*CurrentLine && strchr(sep, *CurrentLine)) { CurrentLine = CurrentLine + 1; j ++; //end of line - no token if (*CurrentLine == '\n') return 0; } //copy token untill next blank i=0; while (1) { //bad line if (! *CurrentLine) { token[i] = 0; return 0; } //end of token or end of line if (strchr(sep, *CurrentLine) || (*CurrentLine == '\n') ) { token[i] = 0; CurrentLine = CurrentLine + 1; return i; } else { token[i] = *CurrentLine; } CurrentLine = CurrentLine + 1; i++; j++; } return 1;}char szFixedVal[5000];char *GetFixedPrintout(char *val){ if (!strcmp(val, "FIX_MIN") || !strcmp(val, "FIX_MAX")) return val; /*composite texture...*/ if (!strcmp(val, "65535")) return "FIX_MAX /*WARNING: modified to allow 16.16 fixed point version!!*/"; sprintf(szFixedVal, "FLT2FIX(%s)", val); return szFixedVal;}BField *BlankField(){ BField *n = malloc(sizeof(BField)); memset(n, 0, sizeof(BField)); return n;}BNode *BlankNode(){ BNode *n = malloc(sizeof(BNode)); memset(n, 0, sizeof(BNode)); n->NDT = gf_list_new(); n->Fields = gf_list_new(); return n;}u8 IsNDT(GF_List *NDTs, char *famName){ u32 i; char *ndtName; for (i=0; i<gf_list_count(NDTs); i++) { ndtName = gf_list_get(NDTs, i); //remove SF / MF as we don't need that if (!strcmp(ndtName+2, famName+2)) return 1; } return 0;}void CheckInTable(char *token, GF_List *NDTs){ u32 i; char *p; for (i=0; i<gf_list_count(NDTs); i++) { p = gf_list_get(NDTs, i); if (!strcmp(p, token)) return; } p = malloc(strlen(token)+1); strcpy(p, token); gf_list_add(NDTs, p);}/*type: 0: header, 1: source*/FILE *BeginFile(char *name, u32 type){ FILE *f; char *cprt = COPYRIGHT_SCENE; char sPath[GF_MAX_PATH]; if (!type) { if (!strcmp(name, "NDT")) { sprintf(sPath, "..%c..%c..%cinclude%cgpac%cinternal%cbifs_tables.h", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR); cprt = COPYRIGHT_BIFS; } /*nodes_mpeg4.h is exported*/ else { sprintf(sPath, "..%c..%c..%cinclude%cgpac%cnodes_mpeg4.h", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR); } } else { if (!stricmp(name, "NDT")) { sprintf(sPath, "..%c..%c..%csrc%cbifs%cbifs_node_tables.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR); cprt = COPYRIGHT_BIFS; } else { sprintf(sPath, "..%c..%c..%csrc%cscenegraph%c%s.c", GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, GF_PATH_SEPARATOR, name); } } f = fopen(sPath, "wt"); fprintf(f, "%s\n", cprt); { time_t rawtime; time(&rawtime); fprintf(f, "\n/*\n\tDO NOT MOFIFY - File generated on GMT %s\n\tBY MPEG4Gen for GPAC Version %s\n*/\n\n", asctime(gmtime(&rawtime)), GPAC_VERSION); } if (!type) { fprintf(f, "#ifndef _%s_H\n", name); fprintf(f, "#define _%s_H\n\n", name); if (!strcmp(name, "nodes_mpeg4")) { fprintf(f, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"); } } return f;}void EndFile(FILE *f, char *name, u32 type){ if (!type) { if (!strcmp(name, "nodes_mpeg4")) { fprintf(f, "#ifdef __cplusplus\n}\n#endif\n\n"); } fprintf(f, "\n\n#endif\t\t/*_%s_H*/\n\n", name); } fclose(f);}void TranslateToken(char *token){ if (!strcmp(token, "+I") || !strcmp(token, "I")) { strcpy(token, "FIX_MAX"); } else if (!strcmp(token, "-I")) { strcpy(token, "FIX_MIN"); }}void WriteNodesFile(GF_List *BNodes, GF_List *NDTs, u32 NumVersions){ FILE *f; u32 i, j; char *NDTName; BNode *n; BField *bf; Bool hasViewport; f = BeginFile("nodes_mpeg4", 0); fprintf(f, "#include <gpac/scenegraph_vrml.h>\n\n"); //write all tags fprintf(f, "\n\nenum {\n"); for (i=0; i<gf_list_count(BNodes); i++) { n = gf_list_get(BNodes, i); if (i) fprintf(f, ",\n\tTAG_MPEG4_%s", n->name); else fprintf(f, "\tTAG_MPEG4_%s = GF_NODE_RANGE_FIRST_MPEG4", n->name); } fprintf(f, ",\n\tTAG_LastImplementedMPEG4\n};\n\n"); for (i=0; i<gf_list_count(BNodes); i++) { n = gf_list_get(BNodes, i); if (n->skip_impl) continue; fprintf(f, "typedef struct _tag%s\n{\n", n->name); fprintf(f, "\tBASE_NODE\n"); /*write children field*/ for (j=0; j<gf_list_count(n->Fields); j++) { bf = gf_list_get(n->Fields, j); if (!stricmp(bf->name, "addChildren") || !strcmp(bf->name, "removeChildren")) continue; if (!strcmp(bf->name, "children") && stricmp(n->name, "audioBuffer")) { fprintf(f, "\tVRML_CHILDREN\n"); break; } } for (j=0; j<gf_list_count(n->Fields); j++) { bf = gf_list_get(n->Fields, j); if (!strcmp(bf->name, "addChildren") || !strcmp(bf->name, "removeChildren")) continue; if (!strcmp(bf->name, "children") && stricmp(n->name, "audioBuffer")) continue; //write remaining fields //eventIn fields are handled as pointer to functions, called by the route manager if (!strcmp(bf->type, "eventIn")) { fprintf(f, "\t%s %s;\t/*eventIn*/\n", bf->familly, bf->name); fprintf(f, "\tvoid (*on_%s)(GF_Node *pThis);\t/*eventInHandler*/\n", bf->name); } else if (!strcmp(bf->type, "eventOut")) { //eventOut fields are handled as an opaque stack pointing to the route manager //this will be refined once the route is in place //we will likely need a function such as: // void SignalRoute(route_stack, node, par) fprintf(f, "\t%s %s;\t/*eventOut*/\n", bf->familly, bf->name); } else if (strstr(bf->familly, "Node")) { //this is a POINTER to a node if (strstr(bf->familly, "SF")) { fprintf(f, "\tGF_Node *%s;\t/*%s*/\n", bf->name, bf->type); } else { //this is a POINTER to a chain fprintf(f, "\tGF_ChildNodeItem *%s;\t/*%s*/\n", bf->name, bf->type); } } else { fprintf(f, "\t%s %s;\t/*%s*/\n", bf->familly, bf->name, bf->type); } } fprintf(f, "} M_%s;\n\n\n", n->name); } hasViewport = 0; //all NDTs are defined in v1 fprintf(f, "/*NodeDataType tags*/\nenum {\n"); for (i=0; i<gf_list_count(NDTs); i++) { NDTName = gf_list_get(NDTs, i); if (!i) { fprintf(f, "\tNDT_%s = 1", NDTName); } else { fprintf(f, ",\n\tNDT_%s", NDTName); } if (strcmp(NDTName, "SFViewportNode")) hasViewport = 1; } //template fix: some node use NDT_SFViewportNode but the table is empty-> not generated if (!hasViewport) fprintf(f, ",\n\tNDT_SFViewportNode"); fprintf(f, "\n};\n\n"); fprintf(f, "/*All BIFS versions handled*/\n"); fprintf(f, "#define GF_BIFS_NUM_VERSION\t\t%d\n\n", NumVersions); fprintf(f, "enum {\n"); for (i=0; i<NumVersions; i++) { if (!i) { fprintf(f, "\tGF_BIFS_V1 = 1,\n"); } else { fprintf(f, "\tGF_BIFS_V%d,\n", i+1); } } fprintf(f, "\tGF_BIFS_LAST_VERSION = GF_BIFS_V%d\n};\n\n", i); fprintf(f, "\n\n"); EndFile(f, "nodes_mpeg4", 0);}u32 IsNodeInTable(BNode *node, char *NDTName){ u32 i; char *ndt; for (i=0; i<gf_list_count(node->NDT); i++) { ndt = gf_list_get(node->NDT, i); if (!strcmp(ndt, NDTName)) return 1; } return 0;}u32 GetBitsCount(u32 MaxVal){ u32 k=0; while ((s32) MaxVal > ((1<<k)-1) ) k+=1; return k;}u32 GetNDTCount(char *NDTName, GF_List *BNodes, u32 Version){ u32 i, nodeCount; BNode *n; //V1 begins at 0 if (Version == 1) { nodeCount = 0; } //V2 at 2 (0 reserved + 1 proto) else if (Version == 2) { nodeCount = 2; } //other at 1 (0 reserved, no proto) else { nodeCount = 1; } for (i=0; i<gf_list_count(BNodes); i++) { n = gf_list_get(BNodes, i); if (n->version != Version) continue; if (!IsNodeInTable(n, NDTName)) continue; nodeCount++; } return nodeCount;}void WriteNDT_H(FILE *f, GF_List *BNodes, GF_List *NDTs, u32 Version)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -