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 + -
显示快捷键?