main.c
来自「gaca源码」· C语言 代码 · 共 1,695 行 · 第 1/4 页
C
1,695 行
/*
* 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 field
typedef 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 node
typedef 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 what
u32 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_List *%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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?